2877: [Noi2012]魔幻棋盘
Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 808 Solved: 317
[ Submit][ Status][ Discuss]
Description
Input
第一行为两个正整数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可能为负数)。
Output
对于每次询问操作,每行输出一个数,表示该区域内所有数的最大公约数。
Sample Input
2 2
1 1
4
6 12
18 24
0 0 0 1 0
1 1 1 1 2 6
1 2 1 2 2 6
0 0 0 1 1
1 1
4
6 12
18 24
0 0 0 1 0
1 1 1 1 2 6
1 2 1 2 2 6
0 0 0 1 1
Sample Output
6 6
HINT
Source
#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;
}