cdq分治——bzoj2683简单题
https://www.lydsy.com/JudgeOnline/problem.php?id=2683
知识点:1.以操作的顺序进行分治
2.cdq分治维护矩阵
3.计算比mid小的给比mid大的的贡献
4.容斥原理
code:
#include <bits/stdc++.h> #define inf 1000000002 #define ll long long using namespace std; int s,w,m; int ans[10005]; int t[2000005]; struct que { int x,y; int val,pos; int id,opt; }q[200005],tmp[200005]; bool operator < (que a,que b) { if(a.x == b.x && a.y == b.y)return a.opt < b.opt; if(a.x == b.x)return a.y < b.y; return a.x < b.x; } void addquery() { int x1,y1,x2,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); int pos = ++ans[0]; q[++m].pos = pos;q[m].id = m;q[m].x = x1 - 1;q[m].y=y1 - 1;q[m].val = 1;q[m].opt = 1; q[++m].pos = pos;q[m].id = m;q[m].x = x2;q[m].y = y2;q[m].val = 1;q[m].opt = 1; q[++m].pos = pos;q[m].id = m;q[m].x = x1 - 1;q[m].y = y2;q[m].val = -1;q[m].opt = 1; q[++m].pos = pos;q[m].id = m;q[m].x = x2;q[m].y = y1 - 1;q[m].val = -1;q[m].opt = 1; } int lowbit(int x) { return x&(-x); } void add(int x,int val) { for(int i=x;i<=w;i+=i&-i)t[i]+=val; } int query(int x) { int tmp = 0; for(int i = x;i;i -= lowbit(i))tmp += t[i]; return tmp; } void cdq(int l,int r) { if(l == r)return; int mid = (l + r) >> 1,l1 = l,l2 = mid + 1; for(int i = l;i <= r;i++) { if(q[i].id <= mid&&!q[i].opt)add(q[i].y,q[i].val); if(q[i].id > mid && q[i].opt)ans[q[i].pos] += q[i].val * query(q[i].y); } for(int i = l;i <= r;i++) if(q[i].id <= mid && !q[i].opt)add(q[i].y,-q[i].val); for(int i = l;i <= r;i++) if(q[i].id <= mid)tmp[l1++] = q[i]; else tmp[l2++] = q[i]; for(int i = l;i <= r;i++) q[i] = tmp[i]; cdq(l,mid);cdq(mid + 1,r); } int main() { scanf("%d%d",&s,&w); while(1) { int opt; scanf("%d",&opt); if(opt == 1) { m++; scanf("%d%d%d",&q[m].x,&q[m].y,&q[m].val); q[m].id = m; } else if(opt == 2) addquery(); else break; } sort(q + 1,q + m + 1); cdq(1,m); for(int i = 1;i <= ans[0];i++) printf("%d\n",ans[i]); return 0; }