题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1176
cdq分治。。
有两维。可以排序搞掉一维然后树状数组处理一维。用cdq分治对时间分治。
对于询问(l,r),(l,mid)一定会对(mid+1,r)有贡献,每次扫一遍把贡献加上去,然后再删掉,把数组重新排一遍序(以保证下次分治的时候不会越界)
#include#include #include #include #define rep(i,l,r) for (int i=l;i<=r;i++)#define down(i,l,r) for (int i=l;i>=r;i--)#define clr(x,y) memset(x,y,sizeof(x))using namespace std;struct data{ int x,y,val,id,pos,a;}q[200500],tmp[200500];int t[2000500],ans[200500];int n,s,m;int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar();} while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} return x*f;}void get(){ ans[0]++; int x1=read(),y1=read(),x2=read(),y2=read(); q[++m].x=x1-1; q[m].y=y1-1; q[m].val=1; q[m].id=m; q[m].pos=1; q[m].a=ans[0]; q[++m].x=x2; q[m].y=y2; q[m].val=1; q[m].id=m; q[m].pos=1; q[m].a=ans[0]; q[++m].x=x1-1; q[m].y=y2; q[m].val=-1; q[m].id=m; q[m].pos=1; q[m].a=ans[0]; q[++m].x=x2; q[m].y=y1-1; q[m].val=-1; q[m].id=m; q[m].pos=1; q[m].a=ans[0];}bool cmp(data a,data b){ if (a.x==b.x&&a.y==b.y) return a.pos mid&&q[i].pos) ans[q[i].a]+=q[i].val*ask(q[i].y); } rep(i,l,r) { if (q[i].id<=mid&&!q[i].pos) add(q[i].y,-q[i].val); } rep(i,l,r) { if (q[i].id<=mid) tmp[l1++]=q[i]; else tmp[l2++]=q[i]; } rep(i,l,r) q[i]=tmp[i]; cdq(l,mid); cdq(mid+1,r);}int main(){ s=read(); n=read(); while (1){ int op=read(); if (op==1) {q[++m].x=read(); q[m].y=read(); q[m].val=read(); q[m].id=m; q[m].pos=0;} if (op==2) get(); if (op==3) break; } sort(q+1,q+1+m,cmp); cdq(1,m); rep(i,1,ans[0]) printf("%d\n",ans[i]+s); return 0;}