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
Sample Output
6 6
一开始觉得直接放在一个二维线段树上,但是太麻烦了(打了20多个if,没有力气debug)
想了一晚上,果断改成两个一维的和一个二维的,好打多了,早上改了一下就A了
首先按点(x,y)把棋盘化成4个部分,然后就相当于只要得到前缀gcd,所以横着差分一下,竖着差分一下,然后把4个矩形拼在一起就变成了正解里的那个奇怪的矩阵
第一次打二维线段树
1 const 2 maxn=500000; 3 type 4 node=record 5 l,r,lc,rc:longint; 6 a:int64; 7 end; 8 var 9 a,b:array[0..maxn]of int64; 10 f,f2:array[0..maxn*4]of node; 11 n,m,t,x,y,tot,cnt,ll,rr,root1,root2:longint; 12 13 function calc(a,b:longint):longint; 14 begin 15 exit((a-1)*m+b); 16 end; 17 18 function gcd(a,b:int64):int64; 19 begin 20 if b=0 then exit(a); 21 exit(gcd(b,a mod b)); 22 end; 23 24 procedure new(x,y,z:longint); 25 begin 26 f2[x].a:=gcd(abs(f2[y].a),abs(f2[z].a)); 27 if f2[x].l=f2[x].r then exit; 28 new(f2[x].lc,f2[y].lc,f2[z].lc); 29 new(f2[x].rc,f2[y].rc,f2[z].rc); 30 end; 31 32 procedure build2(l,r:longint); 33 var 34 now,mid:longint; 35 begin 36 if l>r then exit; 37 inc(cnt);now:=cnt; 38 f2[now].l:=l;f2[now].r:=r; 39 if l=r then 40 begin 41 if ll=rr then f2[now].a:=b[calc(ll,l)]; 42 exit; 43 end; 44 mid:=(l+r)>>1; 45 f2[now].lc:=cnt+1; 46 build2(l,mid); 47 f2[now].rc:=cnt+1; 48 build2(mid+1,r); 49 if ll=rr then f2[now].a:=gcd(abs(f2[f2[now].lc].a),abs(f2[f2[now].rc].a)); 50 end; 51 52 procedure build(l,r:longint); 53 var 54 now,mid:longint; 55 begin 56 if l>r then exit; 57 inc(tot);now:=tot; 58 f[now].l:=l;f[now].r:=r; 59 if l=r then 60 begin 61 f[now].a:=cnt+1; 62 ll:=l;rr:=r; 63 build2(1,m-1); 64 exit; 65 end; 66 mid:=(l+r)>>1; 67 f[now].lc:=tot+1; 68 build(l,mid); 69 f[now].rc:=tot+1; 70 build(mid+1,r); 71 f[now].a:=cnt+1; 72 ll:=l;rr:=r; 73 build2(1,m-1); 74 new(f[now].a,f[f[now].lc].a,f[f[now].rc].a); 75 end; 76 77 function get(now,l,r:longint):int64; 78 var 79 mid:longint; 80 begin 81 if (f2[now].l>=l) and (f2[now].r<=r) then exit(abs(f2[now].a)); 82 mid:=(f2[now].l+f2[now].r)>>1; 83 get:=0; 84 if l<=mid then get:=gcd(get(f2[now].lc,l,r),get); 85 if r>mid then get:=gcd(get(f2[now].rc,l,r),get); 86 end; 87 88 function get(now,x1,y1,x2,y2:longint):int64; 89 var 90 mid:longint; 91 begin 92 if (x1>y1) or (x2>y2) then exit(0); 93 if (f[now].l>=x1) and (f[now].r<=y1) then exit(get(f[now].a,x2,y2)); 94 get:=0;mid:=(f[now].l+f[now].r)>>1; 95 if x1<=mid then get:=gcd(get(f[now].lc,x1,y1,x2,y2),get); 96 if y1>mid then get:=gcd(get(f[now].rc,x1,y1,x2,y2),get); 97 end; 98 99 procedure new(x,y,z,k:longint); 100 var 101 mid:longint; 102 begin 103 f2[x].a:=gcd(abs(f2[y].a),abs(f2[z].a)); 104 if f2[x].l=f2[x].r then exit; 105 mid:=(f2[x].l+f2[x].r)>>1; 106 if k<=mid then new(f2[x].lc,f2[y].lc,f2[z].lc,k) 107 else new(f2[x].rc,f2[y].rc,f2[z].rc,k); 108 end; 109 110 procedure add(now,x:longint;c:int64); 111 var 112 mid:longint; 113 begin 114 if f2[now].l=f2[now].r then 115 begin 116 inc(f2[now].a,c); 117 exit; 118 end; 119 mid:=(f2[now].l+f2[now].r)>>1; 120 if x<=mid then add(f2[now].lc,x,c) 121 else add(f2[now].rc,x,c); 122 f2[now].a:=gcd(abs(f2[f2[now].lc].a),abs(f2[f2[now].rc].a)); 123 end; 124 125 procedure add(now,x,y:longint;c:int64); 126 var 127 mid:longint; 128 begin 129 if (x<1) or (x>=n) or (y<1) or (y>=m) then exit; 130 if f[now].l=f[now].r then 131 begin 132 add(f[now].a,y,c); 133 exit; 134 end; 135 mid:=(f[now].l+f[now].r)>>1; 136 if x<=mid then add(f[now].lc,x,y,c) 137 else add(f[now].rc,x,y,c); 138 new(f[now].a,f[f[now].lc].a,f[f[now].rc].a,y); 139 end; 140 141 procedure main; 142 var 143 i,j,k,x1,y1,x2,y2:longint; 144 c:int64; 145 begin 146 read(n,m,x,y,t); 147 for i:=1 to n do 148 for j:=1 to m do 149 read(a[calc(i,j)]); 150 for i:=1 to n-1 do 151 for j:=1 to m-1 do 152 b[calc(i,j)]:=a[calc(i,j)]+a[calc(i+1,j+1)]-a[calc(i,j+1)]-a[calc(i+1,j)]; 153 build(1,n-1); 154 ll:=rr+1; 155 root1:=cnt+1; 156 build2(1,n); 157 root2:=cnt+1; 158 build2(1,m); 159 for i:=1 to n do 160 if i=x then add(root1,x,a[calc(x,y)]) 161 else 162 if i<x then add(root1,i,a[calc(i,y)]-a[calc(i+1,y)]) 163 else add(root1,i,a[calc(i,y)]-a[calc(i-1,y)]); 164 for i:=1 to m do 165 if i=y then add(root2,y,a[calc(x,y)]) 166 else 167 if i<y then add(root2,i,a[calc(x,i)]-a[calc(x,i+1)]) 168 else add(root2,i,a[calc(x,i)]-a[calc(x,i-1)]); 169 for i:=1 to t do 170 begin 171 read(k,x1,y1,x2,y2); 172 if k=0 then writeln(gcd(gcd(get(1,x-x1,x+x2-1,y-y1,y+y2-1),get(root1,x-x1,x+x2)),get(root2,y-y1,y+y2))) 173 else 174 begin 175 read(c); 176 if (x1<=x) and (x2>=x) and (y1<=y) and (y2>=y) then 177 begin 178 add(root1,x,c); 179 add(root2,y,c); 180 end; 181 if (x1<=x) and (x2>=x) then 182 begin 183 if (y1<=y) and (y1>1) then add(root2,y1-1,-c); 184 if y1>y then add(root2,y1,c); 185 if (y2>=y) and (y2<m) then add(root2,y2+1,-c); 186 if y2<y then add(root2,y2,c); 187 end; 188 if (y1<=y) and (y2>=y) then 189 begin 190 if (x1<=x) and (x1>1) then add(root1,x1-1,-c); 191 if x1>x then add(root1,x1,c); 192 if (x2>=x) and (x2<n) then add(root1,x2+1,-c); 193 if x2<x then add(root1,x2,c); 194 end; 195 add(1,x1-1,y1-1,c); 196 add(1,x1-1,y2,-c); 197 add(1,x2,y2,c); 198 add(1,x2,y1-1,-c); 199 end; 200 end; 201 end; 202 203 begin 204 main; 205 end.