BZOJ 1176 && BZOJ 2683 CDQ分治
2017-01-05 17:11
513 查看
双倍经验题…放到一起了
2.处理左区间修改对右区间询问的影响。
(因为不理解这里看了好久…)
这样做可以保证每一个询问之前的修改都会影响到它的答案。
比如这道题
题目大意:给定一个n*n的矩阵(初始全0),有以下操作:
1.把(x,y)处加上z
2.询问(x1,y1)到(x2,y2)的矩形权值和
n<=100000
矩形很大,二维树状数组不能用了。这时我们使用CDQ分治。
CDQ分治常用于把多维问题减少一维。
首先,把操作全都存起来,需要记录操作类型,x/y坐标,操作相关值。
其中,一个询问可以拆成四个询问。
将其按照x坐标排序,进行分治。
分治过程同上,详细见代码。
这里贴上1176的代码
CDQ分治
也叫做时间分治。即把操作序列按照一定的顺序排序之后以时间为界进行分治。算法过程
1.递归处理左、右区间内部修改对询问的影响。2.处理左区间修改对右区间询问的影响。
(因为不理解这里看了好久…)
这样做可以保证每一个询问之前的修改都会影响到它的答案。
比如这道题
题目大意:给定一个n*n的矩阵(初始全0),有以下操作:
1.把(x,y)处加上z
2.询问(x1,y1)到(x2,y2)的矩形权值和
n<=100000
矩形很大,二维树状数组不能用了。这时我们使用CDQ分治。
CDQ分治常用于把多维问题减少一维。
首先,把操作全都存起来,需要记录操作类型,x/y坐标,操作相关值。
其中,一个询问可以拆成四个询问。
将其按照x坐标排序,进行分治。
分治过程同上,详细见代码。
这里贴上1176的代码
#include <cstdio> #include <algorithm> #define N 200005 using namespace std; inline int lowbit(int x) {return x & -x;} struct Operation { int x,y,mode,pos,num; Operation(){} Operation(int X,int Y,int Mode,int Pos,int Num):x(X),y(Y),mode(Mode),pos(Pos),num(Num){} bool operator < (const Operation& rhs) const {return x<rhs.x;} }p ,sup ; int n,top,T; int c[N*10],k[N*10]; void Change(int x,int v) { while(x<=n) { if(k[x]!=T) c[x]=0; k[x]=T; c[x]+=v; x+=lowbit(x); } return ; } int Query(int x) { int ans=0; while(x) { if(k[x]==T) ans+=c[x]; x-=lowbit(x); } return ans; } bool cmp(const Operation& x,const Operation& y) {return x.pos<y.pos;} void CDQ(int l,int r) { if(l==r) return ; int mid=l+r>>1; int l1=l,l2=mid+1; for(int i=l;i<=r;i++) if(p[i].pos<=mid) sup[l1++]=p[i]; else sup[l2++]=p[i]; for(int i=l;i<=r;i++) p[i]=sup[i]; CDQ(mid+1,r) , CDQ(l,mid); l1=l , l2=mid+1; T++; for(;l2<=r;l2++) { for(;p[l1].x<=p[l2].x && l1<=mid;l1++) if(p[l1].mode==1) Change(p[l1].y,p[l1].num); if(p[l2].mode==2) p[l2].num+=Query(p[l2].y); } l1=l , l2=mid+1; for(int i=l;i<=r;i++) if(p[l1]<p[l2] && l1<=mid || l2>r) sup[i]=p[l1++]; else sup[i]=p[l2++]; for(int i=l;i<=r;i++) p[i]=sup[i]; return ; } int main() { scanf("%d%d",&n,&n); int mode; while(scanf("%d",&mode)==1 && mode!=3) { if(mode==1) { int x,y,z; scanf("%d%d%d",&x,&y,&z); p[++top]=Operation(x,y,1,top,z); } if(mode==2) { int x1,y1,x2,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); p[++top]=Operation(x1-1,y1-1,2,top,0); p[++top]=Operation(x2,y1-1,2,top,0); p[++top]=Operation(x1-1,y2,2,top,0); p[++top]=Operation(x2,y2,2,top,0); } } sort(p+1,p+1+top); CDQ(1,top); sort(p+1,p+1+top,cmp); for(int i=1;i<=top;i++) if(p[i].mode==2){ int ans=0; ans+=p[i++].num; ans-=p[i++].num; ans-=p[i++].num; ans+=p[i].num; printf("%d\n",ans); } return 0; }
相关文章推荐
- BZOJ 1176: [Balkan2007]Mokia&&2683: 简单题|cdq分治
- CDQ分治 【bzoj2683 && bzoj1176】
- bzoj 1176: [Balkan2007]Mokia&&2683: 简单题 -- cdq分治
- Bzoj2683 简单题 [CDQ分治]
- BZOJ 1176: [Balkan2007]Mokia( CDQ分治 + 树状数组 )
- BZOJ 1176 CDQ分治
- BZOJ 1492 斜率优化dp && cdq分治
- 【BZOJ】1176: [Balkan2007]Mokia(cdq分治)
- [BZOJ2683]简单题(cdq分治)
- [BZOJ1492][NOI2007]货币兑换Cash && CDQ分治+斜率优化
- 【BZOJ2683】简单题【CDQ分治】
- bzoj 1176: [Balkan2007]Mokia(cdq分治)
- BZOJ2683 简单题(CDQ分治)
- BZOJ 1176 [Balkan2007]Mokia ——CDQ分治
- bzoj 1176: Mokia CDQ分治
- [BZOJ3295] [Cqoi2011]动态逆序对 && CDQ分治
- bzoj 1176(cdq分治)
- bzoj 1176 Mokia(CDQ分治,BIT)
- BZOJ 1176([Balkan2007]Mokia-CDQ分治-分治询问)
- BZOJ 2683 CDQ分治