【BZOJ1176】Mokia(CDQ分治)
2018-04-09 22:00
309 查看
【BZOJ1176】Mokia(CDQ分治)
题面
BZOJ权限题啊,,,,dbzoj真好
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
HINT
保证答案不会超过int范围题解
很明显,只有时间靠前的修改的才会对时间靠后的修改产生影响。同时,我们有三个维度:时间,\(x\)轴,\(y\)轴
因此,对于时间进行分治,按照\(x\)排序,
但是这样子每次修改后,很不好解决询问的问题。
我们把询问拆开,拆分为\(4\)个询问
啥?哪四个询问,当然是二维前缀和的询问啊。。。
然后就可以\(CDQ\)分治了。。
说起来,这看一眼就可以用树套树秒掉啊。。。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map> #include<vector> #include<queue> using namespace std; #define ll long long #define RG register #define MAX 2222222 #define lb(x) (x&(-x)) inline int read() { RG int x=0,t=1;RG char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=-1,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return x*t; } int S,n,tot,tim,cntq; int c[MAX],ans[MAX]; void add(int x,int w){while(x<=n)c[x]+=w,x+=lb(x);} int getsum(int x){int ret=0;while(x)ret+=c[x],x-=lb(x);return ret;} struct Opter{int t,x,y,w,ot,id;}q[MAX],tmp[MAX]; bool operator<(Opter a,Opter b) { if(a.x!=b.x)return a.x<b.x; if(a.y!=b.y)return a.y<b.y; return a.id<b.id; } void CDQ(int l,int r) { if(l==r)return; int mid=(l+r)>>1; for(int i=l;i<=r;++i) { if(q[i].t<=mid&&q[i].ot==1)add(q[i].y,q[i].w); if(q[i].t>mid&&q[i].ot==2)ans[q[i].id]+=q[i].w*getsum(q[i].y); } for(int i=l;i<=r;++i) if(q[i].t<=mid&&q[i].ot==1)add(q[i].y,-q[i].w); int t1=l-1,t2=mid; for(int i=l;i<=r;++i) if(q[i].t<=mid)tmp[++t1]=q[i]; else tmp[++t2]=q[i]; for(int i=l;i<=r;++i)q[i]=tmp[i]; CDQ(l,mid);CDQ(mid+1,r); } int main() { S=read();n=read(); while(233) { int opt=read(); if(opt==3)break; if(opt==1) { int x=read(),y=read(); q[++tot]=(Opter){++tim,x,y,read(),1}; } else { int x=read(),y=read(),X=read(),Y=read(); ans[++cntq]=(y-Y+1)*(X-x+1)*S;//++tim; q[++tot]=(Opter){++tim,x-1,y-1,+1,2,cntq}; q[++tot]=(Opter){++tim,X,Y,+1,2,cntq}; q[++tot]=(Opter){++tim,x-1,Y,-1,2,cntq}; q[++tot]=(Opter){++tim,X,y-1,-1,2,cntq}; } } sort(&q[1],&q[tot+1]); CDQ(1,tot); for(int i=1;i<=cntq;++i)printf("%d\n",ans[i]); return 0; }
相关文章推荐
- 【bzoj】【1176】【mokia】【cdq分治】
- BZOJ 1176: [Balkan2007]Mokia [CDQ分治]
- [BZOJ1176][[Balkan2007]Mokia][CDQ分治]
- BZOJ 1176 Mokia(CDQ分治)
- bzoj 1176: [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分治)
- 【BZOJ1176】Mokia(CDQ分治)
- [学习笔记]CDQ分治 bzoj1176 [Baltic2007] Mokia
- bzoj 1176 [Balkan2007]Mokia 【CDQ分治】
- BZOJ1176 [Balkan2007]Mokia 【CDQ分治】
- bzoj 1176: Mokia CDQ分治
- BZOJ1176 [Balkan2007]Mokia 【CDQ分治】
- [BZOJ1176]-Mokia-CDQ分治
- cdq分治入门--BZOJ1176: [Balkan2007]Mokia
- bzoj 1176: [Balkan2007]Mokia&&2683: 简单题 -- cdq分治
- 【bzoj 1176】Mokia(CDQ分治)