【TSINSEN-A1483】方格取数【DP】【随机数据】【单调栈】

来源:互联网 发布:商家服务规范 淘宝 编辑:程序博客网 时间:2024/05/18 03:00

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;}


0 0
原创粉丝点击