bzoj3132: 上帝造题的七分钟
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3132: 上帝造题的七分钟相关的知识,希望对你有一定的参考价值。
嗯,裸的二维区间加区间求和
复习了下zkw的求前缀和的前缀和方法:
维护sx[n] = ∑x[i], six[n] = ∑i * x[i]
那么有ssx[n] = sx[n] * (n + 1) - six[n]
用树状数组搞搞就可以啦
很容易推广到二维
#include <bits/stdc++.h> using namespace std; int n, m; int s1[2100][2100], sn[2100][2100], sm[2100][2100], snm[2100][2100]; int lowbit(int t) {return (t & (-t));} void add(int s[][2100], int ni, int mi, int a) { for (int i = ni; i <= n; i += lowbit(i)) for (int j = mi; j <= m; j += lowbit(j)) s[i][j] += a; } int sum(int s[][2100], int ni, int mi) { int a = 0; for (int i = ni; i; i -= lowbit(i)) for (int j = mi; j; j -= lowbit(j)) a += s[i][j]; return a; } void addx(int ni, int mi, int a) { if (ni * mi == 0) return; add(s1, ni, mi, a); add(sn, ni, mi, a * ni); add(sm, ni, mi, a * mi); add(snm, ni, mi, a * ni * mi); } int sumx(int ni, int mi) { if (ni * mi == 0) return 0; return sum(s1, ni, mi) * (ni + 1) * (mi + 1) - sum(sn, ni, mi) * (mi + 1) - sum(sm, ni, mi) * (ni + 1) + sum(snm, ni, mi); } int main() { char ch[2]; scanf("%s%d%d", ch, &n, &m); while (scanf("%s", ch) == 1) { int nl, ml, nr, mr, a = 0; if (ch[0] == ‘L‘) { scanf("%d%d%d%d%d", &nl, &ml, &nr, &mr, &a); addx(nr + 1, mr + 1, a); addx(nl, mr + 1, -a); addx(nr + 1, ml, -a); addx(nl, ml, a); } else { scanf("%d%d%d%d", &nl, &ml, &nr, &mr); printf("%d\n", sumx(nr, mr) - sumx(nl - 1, mr) - sumx(nr, ml - 1) + sumx(nl - 1, ml - 1)); } } }
以上是关于bzoj3132: 上帝造题的七分钟的主要内容,如果未能解决你的问题,请参考以下文章