您的位置:首页 > 其它

bzoj 1176 [Balkan2007]Mokia 【CDQ分治】

2017-12-25 10:57 399 查看
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
,t
,p
,cnt,q
;
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
;
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 }

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: