bzoj1176 [Balkan2007]Mokia(CDQ二维平面)
2017-12-14 15:20
381 查看
Description
维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000.Input
第一行两个整数,S,W;其中S为矩阵初始值;W为矩阵大小接下来每行为一下三种输入之一(不包含引号):
"1 x y a"
"2 x1 y1 x2 y2"
"3"
输入1:你需要把(x,y)(第x行第y列)的格子权值增加a
输入2:你需要求出以左下角为(x1,y1),右上角为(x2,y2)的矩阵内所有格子的权值和,并输出
输入3:表示输入结束
Output
对于每个输入2,输出一行,即输入2的答案Sample Input
0 41 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
Sample Output
35
[Submit][Status][Discuss]
分析:
CDQ分治
详情请参考bzoj2683
唯一不同点是有初始值
然而初始值是面向全体的,所以我们直接在ans上加上(矩阵大小*S)即可
//这里写代码片 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N=2000010; struct node{ int type,x,ya,yb,id,z; }; node po[N<<1]; int tot,totx=0,ans[10010],t ; int n,S; int get(int xa,int ya,int xb,int yb) {return (xb-xa+1)*(yb-ya+1)*S;} void add(int x,int z){for (int i=x;i<=n;i+=(i&(-i))) t[i]+=z;} int ask(int x) {int ans=0;for (int i=x;i>0;i-=(i&(-i))) ans+=t[i];return ans;} int cmp(const node &a,const node &b) { if (a.x!=b.x) return a.x<b.x; else return a.type<b.type; } void CDQ(int L,int R) { if (L==R) return; int M=(L+R)>>1; CDQ(L,M); CDQ(M+1,R); sort(po+L,po+M+1,cmp); sort(po+M+1,po+R+1,cmp); int t1=L,t2=M+1,last=0; while (t2<=R) { while (t1<=M&&po[t1].type!=1) t1++; while (t2<=R&&po[t2].type==1) t2++; if (t1<=M&&po[t1].x<=po[t2].x) { add(po[t1].ya,po[t1].z); last=t1++; } else if (t2<=R) { if (po[t2].type==2) ans[po[t2].id]-=ask(po[t2].yb)-ask(po[t2].ya-1),t2++; else ans[po[t2].id]+=ask(po[t2].yb)-ask(po[t2].ya-1),t2++; } } for (int i=L;i<=last;i++) if (po[i].type==1) add(po[i].ya,-po[i].z); } int main() { scanf("%d%d",&S,&n); for (;;) { int opt,xa,ya,xb,yb,z; scanf("%d",&opt); if (opt==1) { tot++; scanf("%d%d%d",&xa,&ya,&z); po[tot].type=1; po[tot].x=xa; po[tot].ya=ya; po[tot].z=z; } else if (opt==2) { scanf("%d%d%d%d",&xa,&ya,&xb,&yb); tot++; totx++; po[tot].type=2; po[tot].x=xa-1; po[tot].ya=ya; po[tot].yb=yb; po[tot].id=totx; tot++; po[tot].type=3; po[tot].x=xb; po[tot].ya=ya; po[tot].yb=yb; po[tot].id=totx; ans[totx]=get(xa,ya,xb,yb); } else break; } CDQ(1,tot); for (int i=1;i<=totx;i++) printf("%d\n",ans[i]); return 0; }
相关文章推荐
- [BZOJ1176][[Balkan2007]Mokia][CDQ分治]
- bzoj1176: [Balkan2007]Mokia【cdq分治】
- bzoj 1176 [Balkan2007]Mokia - CDQ分治 - 树状数组
- bzoj 1176: [Balkan2007]Mokia(cdq分治)
- CDQ分治——BZOJ1176 [Balkan2007]Mokia
- BZOJ 1176: [Balkan2007]Mokia (CDQ分治)
- cdq分治入门--BZOJ1176: [Balkan2007]Mokia
- BZOJ 1176 [Balkan2007]Mokia [CDQ分治+树状数组]
- BZOJ 1176: [Balkan2007]Mokia | CDQ分治
- BZOJ1176 [Balkan2007]Mokia 【CDQ分治】
- BZOJ1176 [Balkan2007]Mokia 【CDQ分治】
- BZOJ 1176([Balkan2007]Mokia-CDQ分治-分治询问)
- bzoj 1176: [Balkan2007]Mokia 【CDQ分治】
- BZOJ 1176: [Balkan2007]Mokia( CDQ分治 + 树状数组 )
- 【BZOJ】1176: [Balkan2007]Mokia(cdq分治)
- BZOJ 1176: [Balkan2007]Mokia [CDQ分治]
- bzoj 1176 [Balkan2007]Mokia 【CDQ分治】
- BZOJ 1176([Balkan2007]Mokia-CDQ分治-分治询问)
- bzoj 1176: [Balkan2007]Mokia&&2683: 简单题 -- cdq分治
- BZOJ 1176 [Balkan2007]Mokia ——CDQ分治