数据结构(二维线段树,差分): NOI2012 魔幻棋盘
2016-07-15 22:57
323 查看
貌似想复杂了……
#include <iostream> #include <cstring> #include <cstdio> #define mid ((l+r)>>1) using namespace std; const int maxn=20000010; const int maxm=600010; int N,M,Q; struct Array{ long long num[maxm]; long long *operator [](int x){ return &num[(x-1)*M]; } }a,b; long long ABS(long long x){return x>0?x:-x;} long long GCD(long long x,long long y){ return y?GCD(y,x%y):ABS(x); } int cnt,ch[maxn][2]; long long w[maxn]; void Merge(int &x,int p1,int p2,int l,int r){ if(!x)x=++cnt; w[x]=GCD(w[p1],w[p2]); if(l!=r){ Merge(ch[x][0],ch[p1][0],ch[p2][0],l,mid); Merge(ch[x][1],ch[p1][1],ch[p2][1],mid+1,r); } } void Build(int &x,int l,int r,long long t[]){ x=++cnt; if(l==r){ w[x]=t[l]; return; } Build(ch[x][0],l,mid,t); Build(ch[x][1],mid+1,r,t); w[x]=GCD(w[ch[x][0]],w[ch[x][1]]); } int rt[maxm<<2]; void Build(int x,int l,int r){ if(l==r){ Build(rt[x],1,M,a[l]); return; } Build(x<<1,l,mid); Build(x<<1|1,mid+1,r); Merge(rt[x],rt[x<<1],rt[x<<1|1],1,M); } int x,y,tx,ty; int tp,x1,y1,x2,y2; long long d; void Change(int x,int l,int r,long long d){ if(l==r){w[x]+=d;return;} if(mid>=ty)Change(ch[x][0],l,mid,d); else Change(ch[x][1],mid+1,r,d); w[x]=GCD(w[ch[x][0]],w[ch[x][1]]); } void Update(int x,int p1,int p2,int l,int r){ w[x]=GCD(w[p1],w[p2]); if(l==r)return; if(mid>=ty)Update(ch[x][0],ch[p1][0],ch[p2][0],l,mid); else Update(ch[x][1],ch[p1][1],ch[p2][1],mid+1,r); } void Modify(int x,int l,int r,long long d){ if(l==r){ Change(rt[x],1,M,d); return; } if(mid>=tx)Modify(x<<1,l,mid,d); else Modify(x<<1|1,mid+1,r,d); Update(rt[x],rt[x<<1],rt[x<<1|1],1,M); } long long Que(int x,int l,int r){ if(l>=y1&&r<=y2) return w[x]; long long ret=0; if(mid>=y1)ret=Que(ch[x][0],l,mid); if(mid<y2)ret=GCD(ret,Que(ch[x][1],mid+1,r)); return ret; } long long Query(int x,int l,int r){ if(l>=x1&&r<=x2) return Que(rt[x],1,M); long long ret=0; if(mid>=x1)ret=Query(x<<1,l,mid); if(mid<x2)ret=GCD(ret,Query(x<<1|1,mid+1,r)); return ret; } int main(){ freopen("chessa.in","r",stdin); freopen("chessa.out","w",stdout); scanf("%d%d",&N,&M); scanf("%d%d",&x,&y); scanf("%d",&Q); for(int i=1;i<=N;i++) for(int j=1;j<=M;j++) scanf("%lld",&b[i][j]); for(int i=1;i<=N;i++) for(int j=1;j<=M;j++){ a[i][j]=b[i][j]; if(i<x)a[i][j]-=b[i+1][j]; if(i>x)a[i][j]-=b[i-1][j]; if(j<y)a[i][j]-=b[i][j+1]; if(j>y)a[i][j]-=b[i][j-1]; if(i!=x&&j!=y)a[i][j]+=b[i+(i<x?1:-1)][j+(j<y?1:-1)]; } Build(1,1,N); while(Q--){ scanf("%d",&tp); scanf("%d%d",&x1,&y1); scanf("%d%d",&x2,&y2); if(tp==0){ x1=x-x1;x2=x+x2; y1=y-y1;y2=y+y2; printf("%lld\n",Query(1,1,N)); } if(tp==1){ scanf("%lld",&d); { if(x1<=x&&y1<=y){ tx=x1-1;ty=y1-1; if(tx&&ty)Modify(1,1,N,d); } if(x1<=x&&y1>y){ tx=x1-1;ty=y1; if(tx)Modify(1,1,N,-d); } if(x1>x&&y1<=y){ tx=x1;ty=y1-1; if(ty)Modify(1,1,N,-d); } if(x1>x&&y1>y){ tx=x1;ty=y1; Modify(1,1,N,d); } } { if(x1<=x&&y2<y){ tx=x1-1;ty=y2; if(tx)Modify(1,1,N,-d); } if(x1<=x&&y2>=y){ tx=x1-1;ty=y2+1; if(tx&&ty<=M)Modify(1,1,N,d); } if(x1>x&&y2<y){ tx=x1;ty=y2; Modify(1,1,N,d); } if(x1>x&&y2>=y){ tx=x1;ty=y2+1; if(ty<=M)Modify(1,1,N,-d); } } { if(x2<x&&y1<=y){ tx=x2;ty=y1-1; if(ty)Modify(1,1,N,-d); } if(x2<x&&y1>y){ tx=x2;ty=y1; Modify(1,1,N,d); } if(x2>=x&&y1<=y){ tx=x2+1;ty=y1-1; if(tx<=N&&ty)Modify(1,1,N,d); } if(x2>=x&&y1>y){ tx=x2+1;ty=y1; if(tx<=N)Modify(1,1,N,-d); } } { if(x2<x&&y2<y){ tx=x2;ty=y2; Modify(1,1,N,d); } if(x2<x&&y2>=y){ tx=x2;ty=y2+1; if(ty<=M)Modify(1,1,N,-d); } if(x2>=x&&y2<y){ tx=x2+1;ty=y2; if(tx<=N)Modify(1,1,N,-d); } if(x2>=x&&y2>=y){ tx=x2+1;ty=y2+1; if(tx<=N&&ty<=M)Modify(1,1,N,d); } } if(x1<=x&&x2>=x){ if(y1<=y){ tx=x;ty=y1-1; if(ty)Modify(1,1,N,-d); } if(y1>y){ tx=x;ty=y1; Modify(1,1,N,d); } if(y2<y){ tx=x;ty=y2; Modify(1,1,N,d); } if(y2>=y){ tx=x;ty=y2+1; if(ty<=M)Modify(1,1,N,-d); } } if(y1<=y&&y2>=y){ if(x1<=x){ tx=x1-1;ty=y; if(tx)Modify(1,1,N,-d); } if(x1>x){ tx=x1;ty=y; Modify(1,1,N,d); } if(x2<x){ tx=x2;ty=y; Modify(1,1,N,d); } if(x2>=x){ tx=x2+1;ty=y; if(tx<=N)Modify(1,1,N,-d); } } if(x1<=x&&x2>=x&&y1<=y&&y2>=y){ tx=x;ty=y; Modify(1,1,N,d); } } } return 0; }
相关文章推荐
- Scala学习(3)——集合(基本数据结构)
- Linux进程管理(一、 基本概念和数据结构)
- 天梯赛 L2-011. 玩转二叉树(数据结构)
- cdoj 1334 郭大侠与Rabi-Ribi 贪心+数据结构
- 数据结构与算法总结4_排序算法
- 【慢速学数据结构】查找树篇
- 【慢速学数据结构】散列篇
- 数据结构(一) -- 循环队列数组实现
- 数据结构(一)线性表
- 数据结构与算法简记:根据层次顺序存储结构构建二叉树---改进版
- 数据结构初探(部分原创)
- 数据结构与算法MOOC习题解题报告(PART 1:第1课-第5课)
- 校门外的树(线段树写法)
- 数据结构~总结与文章目录
- (续)hdu1800_Fying_to_the_Mars
- 最小生成树算法
- 数据结构 算法
- 数据结构:排序算法
- 浅谈算法和数据结构:栈和队列
- 数据结构 数据结构分类