bzoj 1176 CDQ分治

时间:2024-04-30 20:38:03

思路:首先我们将问题转换一下,变成问在某个点左下角的权值和,那么每一个询问可以拆成4的这样的询问,然后

进行CDQ 分治,回溯的时候按x轴排序,然后用树状数组维护y的值。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int, int>
#define x2 skdjflsdg
#define y2 sdkfjsktge using namespace std; const int N = 2e6 + ;
const int M = 1e6 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 +; int s, w, cnt, tot, op; LL ans[M], a[N];
struct Qus {
int x, y, idx, id;
} qus[M], tmp[M]; void modify(int x, int v) {
for(int i = x; i < N; i += i & -i) {
a[i] += v;
}
} LL sum(int x) {
LL ans = ;
for(int i = x; i; i -= i & -i) {
ans += a[i];
}
return ans;
} void cdq(int l, int r) { if(l == r) return;
int mid = l + r >> ;
cdq(l, mid); cdq(mid + , r); int p = l, q = mid + , cnt = l; for(int i = mid + ; i <= r; i++) {
while(p <= mid && qus[p].x <= qus[i].x) {
if(qus[p].idx == )
modify(qus[p].y, qus[p].id);
p++;
}
ans[qus[i].id] += qus[i].idx * sum(qus[i].y);
} for(int i = l; i < p; i++) {
if(qus[i].idx == ) {
modify(qus[i].y, -qus[i].id);
}
} p = l, q = mid + , cnt = l; while(p <= mid && q <= r) {
if(qus[p].x <= qus[q].x) {
tmp[cnt++] = qus[p++];
} else {
tmp[cnt++] = qus[q++];
}
} while(p <= mid) tmp[cnt++] = qus[p++];
while(q <= r) tmp[cnt++] = qus[q++]; for(int i = l; i <= r; i++) qus[i] = tmp[i]; } int main() {
scanf("%d%d", &s, &w);
while(scanf("%d", &op) && op < ) {
if(op == ) {
int x, y, a; scanf("%d%d%d", &x, &y, &a);
x += ; y += ;
qus[++tot].x = x;
qus[tot].y = y;
qus[tot].id = a;
qus[tot].idx = ;
} else {
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
x1 += , y1 += ;
x2 += , y2 += ;
qus[++tot].x = x2;
qus[tot].y = y2;
qus[tot].id = ++cnt;
qus[tot].idx = ; qus[++tot].x = x2;
qus[tot].y = y1 - ;
qus[tot].id = cnt;
qus[tot].idx = -; qus[++tot].x = x1 - ;
qus[tot].y = y2;
qus[tot].id = cnt;
qus[tot].idx = -; qus[++tot].x = x1 - ;
qus[tot].y = y1 - ;
qus[tot].id = cnt;
qus[tot].idx = ; ans[cnt] = 1ll * (x2 - x1) * (y2 - y1) * s;
}
}
cdq(, tot);
for(int i = ; i <= cnt; i++)
printf("%lld\n", ans[i]);
return ;
}
/*
*/