我的第一道cdq分治
需要注意的是排序时一定要把询问放前边
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int MAXN=500005; const int MAXQ=800005; const int MAXM=200005; inline void swap(int &x,int &y){ int z=x;x=y;y=z; } inline int read(){ int x=0,f=1,ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } int data[MAXN],n; inline void add(int x,int i){ while(x<=n) data[x]+=i,x+=x&(-x); } inline int query(int x){ int res=0; while(x) res+=data[x],x-=x&(-x); return res; } struct stu{ int op,id,x,y,z; }; inline int cmp(stu a,stu b){ if(a.x==b.x) return a.op<b.op; return a.x<b.x; } stu q[MAXQ],q1[MAXQ]; int ans[MAXM]; inline void solve(int l,int r){ // cout<<l<<"\t"<<r<<endl; if(l==r) return ; int mid=(l+r)>>1,cnt1=0; for(int i=l;i<=mid;i++) if(!q[i].op) q1[++cnt1]=q[i]; for(int i=mid+1;i<=r;i++) if(q[i].op) q1[++cnt1]=q[i]; sort(q1+1,q1+1+cnt1,cmp); // cout<<cnt1<<endl; for(int i=1;i<=cnt1;i++){ if(!q1[i].op) add(q1[i].y,q1[i].z); else if(q1[i].op==1) ans[q1[i].id]+=query(q1[i].y); else ans[q1[i].id]-=query(q1[i].y); } for(int i=1;i<=cnt1;i++) if(!q1[i].op) add(q1[i].y,-q1[i].z); solve(l,mid);solve(mid+1,r); } int main(){ freopen("locust.in","r",stdin); freopen("locust.out","w",stdout); memset(ans,-1,sizeof(ans)); n=read(); int Q=read(); int cnt=0; for(int i=1;i<=Q;i++){ int op=read(); if(op==1) q[++cnt].op=0,q[cnt].x=read(),q[cnt].y=read(),q[cnt].z=read(); else{ ans[i]=0; int x1=read(),y1=read(),x2=read(),y2=read(); if(x1>x2) swap(x1,x2); if(y1>y2) swap(y1,y2); q[++cnt].op=1,q[cnt].x=x1-1,q[cnt].y=y1-1,q[cnt].id=i; q[++cnt].op=2,q[cnt].x=x1-1,q[cnt].y=y2,q[cnt].id=i; q[++cnt].op=2,q[cnt].x=x2,q[cnt].y=y1-1,q[cnt].id=i; q[++cnt].op=1,q[cnt].x=x2,q[cnt].y=y2,q[cnt].id=i; } } solve(1,cnt); for(int i=1;i<=Q;i++) if(ans[i]!=-1) printf("%d\n",ans[i]); return 0; }
原文:https://www.cnblogs.com/gcyyzf/p/9759227.html