2013年集训队论文题。
看了题解后我是大写的懵逼。
(这OJ竟然还有代码风格分)
/* Footprints In The Blood Soaked Snow */ #include <cstdio> #include <algorithm> #include <queue> #include <vector> using namespace std; typedef long long LL; const int maxn = 200005, maxlogn = 505; const LL inf = 0x3f3f3f3f3f3f3f3f; int n; int al[maxn], ar[maxn], bl[maxn], br[maxn], A[maxn], B[maxn]; LL suma[maxn], sumb[maxn], dp[maxlogn][maxlogn]; inline int iread() { int f = 1, x = 0; char ch = getchar(); for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1; for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0'; return f * x; } int sta[maxn]; void calc(int *x, int *L, int *R) { int top; for(int i = 1; i <= n; i++) L[i] = 0, R[i] = n + 1; top = 0; for(int i = 1; i <= n; i++) { for(; top && x[i] <= x[sta[top]]; top--) R[sta[top]] = i; sta[++top] = i; } top = 0; for(int i = n; i >= 1; i--) { for(; top && x[i] <= x[sta[top]]; top--) L[sta[top]] = i; sta[++top] = i; } } int X[maxn], Y[maxn]; inline LL solve(int x1, int y1, int x2, int y2) { int topx = 0, topy = 0; for(int i = x1; i <= x2; i = br[i]) X[++topx] = i; for(int i = x2; i >= x1; i = bl[i]) X[++topx] = i; for(int i = y1; i <= y2; i = ar[i]) Y[++topy] = i; for(int i = y2; i >= y1; i = al[i]) Y[++topy] = i; sort(X + 1, X + topx + 1); topx = unique(X + 1, X + topx + 1) - (X + 1); sort(Y + 1, Y + topy + 1); topy = unique(Y + 1, Y + topy + 1) - (Y + 1); for(int i = 1; i <= topx; i++) for(int j = 1; j <= topy; j++) { if(i == 1 && j == 1) { dp[i][j] = (LL)A[Y[i]] * B[X[j]]; continue; } LL ans1 = inf, ans2 = inf; if(j != 1) ans1 = dp[i][j - 1] + (LL)B[X[i]] * (suma[Y[j]] - suma[Y[j - 1]]); if(i != 1) ans2 = dp[i - 1][j] + (LL)A[Y[j]] * (sumb[X[i]] - sumb[X[i - 1]]); dp[i][j] = min(ans1, ans2); } return dp[topx][topy]; } int main() { n = iread(); int T = iread(); for(int i = 1; i <= n; i++) suma[i] = suma[i - 1] + (A[i] = iread()); calc(A, al, ar); for(int i = 1; i <= n; i++) sumb[i] = sumb[i - 1] + (B[i] = iread()); calc(B, bl, br); while(T--) { int x1 = iread(), y1 = iread(), x2 = iread(), y2 = iread(); swap(x1, y1); swap(x2, y2); printf("%lld\n", solve(x1, y1, x2, y2)); } return 0; }