记录编号 283775 评测结果 AAAAAAAAAA
题目名称 [NOI 2012]魔幻棋盘 最终得分 100
用户昵称 GravatarTenderRun 是否通过 通过
代码语言 C++ 运行时间 9.680 s
提交时间 2016-07-15 14:33:39 内存使用 323.80 MiB
显示代码纯文本
#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;
}