bzoj2683 简单题

  这题可以用cdq分治套树状数组,递归的每一层只考虑左半部分的修改对右半部分的询问所出产生的影响,至于左半部分的询问和右半部分修改对右半部分的询问的影响则递归下去处理,这样就没有顺序的影响,变成只考虑先插入后修改的情况。这种情况把每个询问拆成两个子询问:查询矩形(x1,1,x2,y1-1)和(x1,1,x2,y2)的值,把后者减去前者就是矩形(x1,y1,x2,y2)的价值,把询问和修改一起按y坐标排序,然后按顺序用树状数组维护修改和查询。

代码

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<map>
  4 #include<cstring>
  5 #include<vector>
  6 #include<string>
  7 #define N 500010
  8 #define M 1010
  9 #define P 1000000007
 10 using namespace std;
 11 int n,typ,m,i,j,tot,x,y,z,b[N],flag[N],ans[N],c[N];
 12 int x1,y1,x2,y2; 
 13 struct g
 14 {
 15     int l,r,typ,v,idx,y,ridx;
 16 }a[N];
 17 bool cmp(g a,g b)
 18 {
 19     if (a.y!=b.y) return a.y<b.y;
 20     return a.ridx<b.ridx;
 21 }
 22 int lowbit(int x)
 23 {
 24     return x&-x;
 25 }
 26 void cc(int x,int w)
 27 {
 28     while (x<=tot)
 29     {
 30         c[x]=c[x]+w;
 31         x=x+lowbit(x);
 32     }
 33 }
 34 int sum(int x)
 35 {
 36     int ans=0;
 37     while (x)
 38     {
 39         ans=ans+c[x];
 40         x=x-lowbit(x);
 41     }
 42     return ans;
 43 }
 44 int ef(int x)
 45 {
 46     int l,r,m;
 47     l=1;r=tot;
 48     while (l<=r)
 49     {
 50         m=(l+r)>>1;
 51         if (b[m]>=x) r=m-1;else l=m+1;
 52     }
 53     return l;
 54 }
 55 void cdq(int l,int r)
 56 {
 57     int m,i;
 58     m=(l+r)>>1;
 59     if (l==r) return;
 60     cdq(l,m);
 61     cdq(m+1,r);
 62     sort(a+l,a+r+1,cmp);
 63     for (i=l;i<=r;i++)
 64     {
 65         if ((a[i].ridx<=m)&&(!a[i].typ)) cc(a[i].l,a[i].v);
 66         if ((a[i].ridx>m)&&(a[i].typ)) ans[a[i].idx]+=((sum(a[i].r)-sum(a[i].l-1))*a[i].typ);
 67     }
 68     for (i=l;i<=r;i++)
 69         if ((a[i].ridx<=m)&&(!a[i].typ)) cc(a[i].l,-a[i].v);
 70 }
 71 int main()
 72 {
 73     scanf("%d",&n);
 74     n=0;
 75     while (1)
 76     {
 77         scanf("%d",&typ);
 78         m++;
 79         if (typ==1)
 80         {
 81             scanf("%d%d%d",&x,&y,&z);
 82             n++;
 83             a[n].y=y;a[n].l=x;a[n].r=x;
 84             a[n].typ=0;a[n].idx=m;a[n].v=z;a[n].ridx=n;
 85             tot++;b[tot]=x;
 86         }
 87         else
 88         if (typ==2)
 89         {
 90             scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
 91             n++;
 92             a[n].y=y1-1;a[n].l=x1;a[n].r=x2;a[n].idx=m;a[n].typ=-1;a[n].ridx=n;
 93             n++;
 94             a[n].y=y2;  a[n].l=x1;a[n].r=x2;a[n].idx=m;a[n].typ=1;a[n].ridx=n;
 95             flag[m]=1;
 96             tot++;b[tot]=x1;
 97             tot++;b[tot]=x2;
 98         }
 99         else
100         break;
101     }
102     sort(b+1,b+1+tot);
103     for (i=1;i<=tot;i++)
104     if (b[i]!=b[i-1])
105     {
106         j++;b[j]=b[i];
107     }
108     tot=j;
109     for (i=1;i<=n;i++)
110     {
111         a[i].l=ef(a[i].l);
112         a[i].r=ef(a[i].r);
113     }
114     cdq(1,n);
115     for (i=1;i<=m;i++)
116     if (flag[i])
117     printf("%d
",ans[i]);
118 }

  这题还有一个强制在线的版本bzoj4066,可以用kdtree解决

原文地址:https://www.cnblogs.com/fzmh/p/4523244.html