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 }

 

 
posted @ 2017-12-25 10:57  lokiii  阅读(170)  评论(0编辑  收藏  举报