bzoj 1176 [Balkan2007]Mokia 【CDQ分治】
W过大,很难在线维护,考虑离线算法
给每个操作加一个时间属性n,显然,对于n=i的询问,对它有影响的修改只在n<i中,所以可以CDQ(因为是按时间序读进来的,所以不用排序了
对于统计矩形和,可以使用二维前缀和的思想,即只需要统计四个点即可
这样就转化成了三维偏序问题,只是询问和修改要分开处理。
(初始值不用管,输出的时候加上就行
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 const int N=2000005; 6 int n,s,qu,tot,ans[N],t[N],p[N],cnt,q[N]; 7 struct qwe 8 { 9 int o,x,y,v,n; 10 qwe(){} 11 qwe(int a1,int a2,int a3,int a4,int a5) 12 { 13 o=a1,x=a2,y=a3,v=a4,n=a5; 14 } 15 }a[N]; 16 bool cmp(const qwe &a,const qwe &b) 17 { 18 return (a.x==b.x&&a.y==b.y&&a.o<b.o)||(a.x==b.x&&a.y<b.y)||(a.x<b.x); 19 } 20 int read() 21 { 22 int r=0,f=1; 23 char p=getchar(); 24 while(p>'9'||p<'0') 25 { 26 if(p=='-') 27 f=-1; 28 p=getchar(); 29 } 30 while(p>='0'&&p<='9') 31 { 32 r=r*10+p-48; 33 p=getchar(); 34 } 35 return r*f; 36 } 37 int lb(int x) 38 { 39 return x&(-x); 40 } 41 void update(int x,int v) 42 { 43 for(int i=x;i<=n;i+=lb(i)) 44 t[i]+=v; 45 } 46 int ques(int x) 47 { 48 int r=0; 49 for(int i=x;i>=1;i-=lb(i)) 50 r+=t[i]; 51 return r; 52 } 53 void cdq(int l,int r) 54 { 55 if(l==r) 56 return; 57 int mid=(l+r)/2,tmp=0; 58 cdq(l,mid); 59 cdq(mid+1,r); 60 sort(a+l,a+mid+1,cmp); 61 sort(a+mid+1,a+r+1,cmp); 62 int i=l,j=mid+1; 63 while(j<=r) 64 { 65 for(;a[i].o==2&&i<=mid;i++); 66 for(;a[j].o==1&&j<=r;j++); 67 if(i<=mid&&a[i].x<=a[j].x) 68 update(a[i].y,a[i].v),i++,tmp=i-1; 69 else if(j<=r) 70 ans[a[j].n]+=ques(a[j].y),j++; 71 } 72 for(int t=l;t<=tmp;t++) 73 if(a[t].o==1) 74 update(a[t].y,-a[t].v); 75 } 76 int main() 77 { 78 s=read();n=read(); 79 while(1) 80 { 81 qu=read(); 82 if(qu==3) 83 break; 84 if(qu==1) 85 { 86 int x=read(),y=read(),z=read(); 87 a[++tot]=qwe(1,x,y,z,tot); 88 } 89 else 90 { 91 int x1=read(),y1=read(),x2=read(),y2=read(); 92 p[++cnt]=tot; 93 q[cnt]=(x2-x1+1)*(y2-y1+1)*s; 94 a[++tot]=qwe(2,x1-1,y1-1,0,tot); 95 a[++tot]=qwe(2,x2,y2,0,tot); 96 a[++tot]=qwe(2,x1-1,y2,0,tot); 97 a[++tot]=qwe(2,x2,y1-1,0,tot); 98 } 99 } 100 cdq(1,tot); 101 for(int i=1;i<=cnt;i++) 102 printf("%d\n",q[i]+ans[p[i]+1]+ans[p[i]+2]-ans[p[i]+3]-ans[p[i]+4]); 103 return 0; 104 }