第一行为两个正整数N,M,表示棋盘的大小。 第二行为两个正整数X,Y,表示棋盘守护者的位置。 第三行仅有一个正整数T,表示棋盘守护者将进行次操作。 接下来N行,每行有M个正整数,用来描述初始时棋盘上每个位置的数。 接下来T行,按操作的时间顺序给出T次操作。每行描述一次操作,以一个数字0或1开头: 若以数字0开头,表示此操作为询问,随后会有四个非负整数x1,y1,x2,y2,表示询问的区域是以棋盘守护者的位置为基础向上扩展x1行,向下扩展y1行,向左扩展x2列,向右扩展y2列得到的矩形区域(详见样例)。 若以数字1开头,表示此操作为修改,随后会有四个正整数x1,y1,x2,y2和一个整数c,表示修改区域的上、下边界分别为第x1,x2行,左、右边界分别为第y1,y2列(详见样例),在此矩形区域内的所有数统一加上c(注意c可能为负数)。
对于每次询问操作,每行输出一个数,表示该区域内所有数的最大公约数。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<vector> using namespace std; const int maxn = 5E5 + 10; const int dx[4][4] = {{0,0,1,1},{0,0,1,1},{0,0,-1,-1},{0,0,-1,-1}}; const int dy[4][4] = {{0,1,0,1},{0,-1,0,-1},{0,1,0,1},{0,-1,0,-1}}; typedef long long LL; LL c[maxn*25]; int n,m,t,x,y,X1,X2,Y1,Y2,cnt = 0,tt,lc[maxn*20],rc[maxn*20]; int jx[10],jy[10],cur; vector <LL> v[maxn]; vector <int> bo[maxn]; LL gcd(LL a,LL b) {return b?gcd(b,a%b):a;} LL ABS(LL x) {return x>0?x:x*-1;} void PRE(int l,int r,int o) { cnt = max(cnt,o); if (l == r) return; int mid = (l+r) >> 1; PRE(l,mid,2*o); PRE(mid+1,r,2*o+1); } LL que(int o,int l,int r,int ql,int qr) { if (ql <= l && r <= qr) return ABS(c[o]); LL ret = 0; int mid = (l+r) >> 1; if (ql <= mid) ret = gcd(ret,que(lc[o],l,mid,ql,qr)); if (qr > mid) ret = gcd(ret,que(rc[o],mid+1,r,ql,qr)); return ret; } LL Modi(int l,int r,int o,int pos,LL va,int typ) { if (l == r) {if (typ) c[o] = va; else c[o] += va; return ABS(c[o]);} int mid = (l+r) >> 1; LL ret; if (pos <= mid) { if (!lc[o]) lc[o] = ++cnt; ret = Modi(l,mid,lc[o],pos,va,typ); } else { if (!rc[o]) rc[o] = ++cnt; ret = Modi(mid+1,r,rc[o],pos,va,typ); } c[o] = gcd(ABS(c[lc[o]]),ABS(c[rc[o]])); return ret; } LL Modify(int l,int r,int o,int pn,int pm,LL va) { if (!pn || !pm || pn > n || pm > m) return -1; if (l == r) return Modi(1,m,o,pm,va,0); int mid = (l+r) >> 1; LL ret1,ret2; if (pn <= mid) { ret1 = Modify(l,mid,2*o,pn,pm,va); ret2 = que(2*o+1,1,m,pm,pm); } else { ret1 = Modify(mid+1,r,2*o+1,pn,pm,va); ret2 = que(2*o,1,m,pm,pm); } return Modi(1,m,o,pm,gcd(ret1,ret2),1); } LL getLL() { LL ret = 0; LL xx = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') xx = -1; ch = getchar(); } while ('0' <= ch && ch <= '9') ret = ret*10 + 1LL*(ch-'0'),ch = getchar(); return ret*xx; } void Judge(int px,int py,LL c) { if (!px || !py || px > n || py > m || px == x || py == y) return; if (bo[px][py] == tt) return; int po; if (px < x && py < y) po = 0; else if (px < x && py > y) po = 1; else if (px > x && py < y) po = 2; else po = 3; LL tot = 0; for (int l = 0; l < 4; l++) { int xx = px + dx[po][l]; int yy = py + dy[po][l]; LL t; if ((!dx[po][l] || !dy[po][l]) && dx[po][l] != dy[po][l]) t = -1; else t = 1; if (X1 <= xx && xx <= X2 && Y1 <= yy && yy <= Y2) tot += c*t; } if (tot != 0) Modify(1,n,1,px,py,tot),bo[px][py] = tt,jx[cur] = px,jy[cur++] = py; } LL query(int o,int l,int r,int nl,int nr,int ml,int mr) { if (nl <= l && r <= nr) return que(o,1,m,ml,mr); LL ret = 0; int mid = (l+r) >> 1; if (nl <= mid) ret = gcd(ret,query(2*o,l,mid,nl,nr,ml,mr)); if (nr > mid) ret = gcd(ret,query(2*o+1,mid+1,r,nl,nr,ml,mr)); return ret; } int main() { #ifdef YZY //freopen("chess1.in","r",stdin); //freopen("test.txt","w",stdout); #endif cin >> n >> m >> x >> y >> t; PRE(1,n,1); for (int i = 1; i <= n; i++) { v[i].push_back(0); bo[i].push_back(0); for (int j = 1; j <= m; j++) { LL x; x = getLL(); v[i].push_back(x); bo[i].push_back(0); } } for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { if (i == x && j == y) Modify(1,n,1,i,j,v[i][j]); else if (i == x && j < y) Modify(1,n,1,i,j,v[i][j]-v[i][j+1]); else if (i == x && j > y) Modify(1,n,1,i,j,v[i][j]-v[i][j-1]); else if (j == y && i < x) Modify(1,n,1,i,j,v[i][j]-v[i+1][j]); else if (j == y && i > x) Modify(1,n,1,i,j,v[i][j]-v[i-1][j]); else if (i < x && j < y) Modify(1,n,1,i,j,v[i][j]-v[i+1][j]-v[i][j+1]+v[i+1][j+1]); else if (i < x && j > y) Modify(1,n,1,i,j,v[i][j]-v[i+1][j]-v[i][j-1]+v[i+1][j-1]); else if (i > x && j < y) Modify(1,n,1,i,j,v[i][j]-v[i-1][j]-v[i][j+1]+v[i-1][j+1]); else Modify(1,n,1,i,j,v[i][j]-v[i][j-1]-v[i-1][j]+v[i-1][j-1]); } while(t--) { int typ = getLL(); if (typ == 0) { X1 = getLL(); Y1 = getLL(); X2 = getLL(); Y2 = getLL(); X1 = x - X1; X2 = x + X2; Y1 = y - Y1; Y2 = y + Y2; printf("%lld\n",query(1,1,n,X1,X2,Y1,Y2)); } else { ++tt; X1 = getLL(); Y1 = getLL(); X2 = getLL(); Y2 = getLL(); LL c; c = getLL(); cur = 0; Judge(X1-1,Y1-1,c); Judge(X1,Y1-1,c); Judge(X1,Y1,c); Judge(X1-1,Y1,c); Judge(X1-1,Y2,c); Judge(X1-1,Y2+1,c); Judge(X1,Y2+1,c); Judge(X1,Y2,c); Judge(X2,Y1,c); Judge(X2+1,Y1,c); Judge(X2+1,Y1-1,c); Judge(X2,Y1-1,c); Judge(X2,Y2,c); Judge(X2,Y2+1,c); Judge(X2+1,Y2,c); Judge(X2+1,Y2+1,c); if (X1 <= x && x <= X2 && Y1 <= y && y <= Y2) Modify(1,n,1,x,y,c); if (X1 <= x && x <= X2) { if (Y1 <= y && y <= Y2) Modify(1,n,1,x,Y2+1,-c),Modify(1,n,1,x,Y1-1,-c); else if (y > Y2) Modify(1,n,1,x,Y2,c),Modify(1,n,1,x,Y1-1,-c); else Modify(1,n,1,x,Y1,c),Modify(1,n,1,x,Y2+1,-c); } if (Y1 <= y && y <= Y2) { if (X1 <= x && x <= X2) Modify(1,n,1,X1-1,y,-c),Modify(1,n,1,X2+1,y,-c); else if (x > X2) Modify(1,n,1,X2,y,c),Modify(1,n,1,X1-1,y,-c); else Modify(1,n,1,X1,y,c),Modify(1,n,1,X2+1,y,-c); } } } return 0; }