这道题第一眼看到想用二维树状数组去做, 发现数据范围太大了根本开不下, 然后考虑用
分治去做, 因为之前用
分治做过树状数组模板, 所以我对其采取了同样的套路, 对序列修改只需要把一个询问拆成两个前缀和, 在这里我们把一个询问拆成四个前缀和, 时间这一维默认是有序的, 那么我们
分治对
排序, 树状数组直接维护
的值就好了
题目链接
Codes
#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)
#define mid ((l + r) >> 1)
using namespace std;
const int maxn = 5e5 + 10, maxq = 8e5 + 10;
int n, cnt, tot, ans[maxn], vis[maxq];
namespace Fenwick_Tree {
int s[maxn];
void update(int x, int y) {
while(x <= n) {
s[x] += y;
x += x & -x;
}
}
int query(int x) {
int res = 0;
while(x) {
res += s[x];
x -= x & -x;
}
return res;
}
}
struct node {
int x, y, z, opt, id;
}Q[maxq], tmp[maxq];
void CDQ(int l, int r) {
if(l == r) return;
CDQ(l, mid), CDQ(mid + 1, r);
int t = l, t1 = l, t2 = mid + 1;
while(t1 <= mid && t2 <= r)
if(Q[t1].x <= Q[t2].x) {
if(!Q[t1].opt) {
Fenwick_Tree::update(Q[t1].y, Q[t1].z);
vis[t] = true;
}
tmp[t ++] = Q[t1 ++];
}
else {
ans[Q[t2].id] += Q[t2].opt * Fenwick_Tree::query(Q[t2].y);
tmp[t ++] = Q[t2 ++];
}
while(t1 <= mid) tmp[t ++] = Q[t1 ++];
while(t2 <= r) {
ans[Q[t2].id] += Q[t2].opt * Fenwick_Tree::query(Q[t2].y);
tmp[t ++] = Q[t2 ++];
}
For(i, l, r) {
if(vis[i]) Fenwick_Tree::update(tmp[i].y, -tmp[i].z);
Q[i] = tmp[i], vis[i] = 0;
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("2683.in", "r", stdin);
freopen("2683.out", "w", stdout);
#endif
int k, X1, X2, Y1, Y2;
scanf("%d", &n);
while(scanf("%d", &k) && k != 3) {
if(k == 1)
++ cnt, scanf("%d%d%d", &Q[cnt].x, &Q[cnt].y, &Q[cnt].z);
else {
scanf("%d%d%d%d", &X1, &Y1, &X2, &Y2), ++ tot;
Q[++ cnt].opt = 1, Q[cnt].x = X2, Q[cnt].y = Y2, Q[cnt].id = tot;
Q[++ cnt].opt = 1, Q[cnt].x = X1 - 1, Q[cnt].y = Y1 - 1, Q[cnt].id = tot;
Q[++ cnt].opt = -1, Q[cnt].x = X1 - 1, Q[cnt].y = Y2, Q[cnt].id = tot;
Q[++ cnt].opt = -1, Q[cnt].x = X2, Q[cnt].y = Y1 - 1, Q[cnt].id = tot;
}
}
CDQ(1, cnt);
For(i, 1, tot)
printf("%d\n", ans[i]);
return 0;
}