数据结构(二维线段树,差分): NOI2012 魔幻棋盘

 

  貌似想复杂了……

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #define mid ((l+r)>>1)
  5 using namespace std;
  6 const int maxn=20000010;
  7 const int maxm=600010;
  8 int N,M,Q;
  9 struct Array{
 10     long long num[maxm];
 11     long long *operator [](int x){
 12         return &num[(x-1)*M];
 13     }
 14 }a,b;
 15 
 16 long long ABS(long long x){return x>0?x:-x;}
 17 long long GCD(long long x,long long y){
 18     return y?GCD(y,x%y):ABS(x);
 19 }
 20 
 21 int cnt,ch[maxn][2];
 22 long long w[maxn];
 23 
 24 void Merge(int &x,int p1,int p2,int l,int r){
 25     if(!x)x=++cnt;
 26     w[x]=GCD(w[p1],w[p2]);
 27     if(l!=r){
 28         Merge(ch[x][0],ch[p1][0],ch[p2][0],l,mid);
 29         Merge(ch[x][1],ch[p1][1],ch[p2][1],mid+1,r);
 30     }
 31 }
 32 
 33 void Build(int &x,int l,int r,long long t[]){
 34     x=++cnt;
 35     if(l==r){
 36         w[x]=t[l];
 37         return;
 38     }
 39     Build(ch[x][0],l,mid,t);
 40     Build(ch[x][1],mid+1,r,t);
 41     w[x]=GCD(w[ch[x][0]],w[ch[x][1]]);
 42 }
 43 
 44 int rt[maxm<<2];
 45 void Build(int x,int l,int r){
 46     if(l==r){
 47         Build(rt[x],1,M,a[l]);
 48         return;
 49     }
 50     Build(x<<1,l,mid);
 51     Build(x<<1|1,mid+1,r);
 52     Merge(rt[x],rt[x<<1],rt[x<<1|1],1,M);
 53 }
 54 
 55 int x,y,tx,ty;
 56 int tp,x1,y1,x2,y2;
 57 long long d;
 58 
 59 void Change(int x,int l,int r,long long d){
 60     if(l==r){w[x]+=d;return;}
 61     if(mid>=ty)Change(ch[x][0],l,mid,d);
 62     else Change(ch[x][1],mid+1,r,d);
 63     w[x]=GCD(w[ch[x][0]],w[ch[x][1]]);
 64 }
 65 
 66 void Update(int x,int p1,int p2,int l,int r){
 67     w[x]=GCD(w[p1],w[p2]);
 68     if(l==r)return;
 69     if(mid>=ty)Update(ch[x][0],ch[p1][0],ch[p2][0],l,mid);
 70     else Update(ch[x][1],ch[p1][1],ch[p2][1],mid+1,r);
 71 }
 72 
 73 void Modify(int x,int l,int r,long long d){
 74     if(l==r){
 75         Change(rt[x],1,M,d);
 76         return;
 77     }
 78     if(mid>=tx)Modify(x<<1,l,mid,d);
 79     else Modify(x<<1|1,mid+1,r,d);
 80     Update(rt[x],rt[x<<1],rt[x<<1|1],1,M);
 81 }
 82 
 83 long long Que(int x,int l,int r){
 84     if(l>=y1&&r<=y2)
 85         return w[x];
 86     long long ret=0;
 87     if(mid>=y1)ret=Que(ch[x][0],l,mid);
 88     if(mid<y2)ret=GCD(ret,Que(ch[x][1],mid+1,r));
 89     return ret;    
 90 }
 91 
 92 long long Query(int x,int l,int r){
 93     if(l>=x1&&r<=x2)
 94         return Que(rt[x],1,M);
 95     long long ret=0;
 96     if(mid>=x1)ret=Query(x<<1,l,mid);
 97     if(mid<x2)ret=GCD(ret,Query(x<<1|1,mid+1,r));
 98     return ret;
 99 } 
100 
101 int main(){
102     freopen("chessa.in","r",stdin);
103     freopen("chessa.out","w",stdout);
104     scanf("%d%d",&N,&M);
105     scanf("%d%d",&x,&y);
106     scanf("%d",&Q);
107     for(int i=1;i<=N;i++)
108         for(int j=1;j<=M;j++)
109             scanf("%lld",&b[i][j]);
110     for(int i=1;i<=N;i++)
111         for(int j=1;j<=M;j++){
112             a[i][j]=b[i][j];
113             if(i<x)a[i][j]-=b[i+1][j];
114             if(i>x)a[i][j]-=b[i-1][j];
115             if(j<y)a[i][j]-=b[i][j+1];
116             if(j>y)a[i][j]-=b[i][j-1];
117             if(i!=x&&j!=y)a[i][j]+=b[i+(i<x?1:-1)][j+(j<y?1:-1)];
118         }
119         
120     Build(1,1,N);
121     while(Q--){
122         scanf("%d",&tp);
123         scanf("%d%d",&x1,&y1);
124         scanf("%d%d",&x2,&y2);
125         if(tp==0){
126             x1=x-x1;x2=x+x2;
127             y1=y-y1;y2=y+y2;
128             printf("%lld\n",Query(1,1,N));
129         }
130         if(tp==1){
131             scanf("%lld",&d);
132             
133             {
134                 if(x1<=x&&y1<=y){
135                     tx=x1-1;ty=y1-1;
136                     if(tx&&ty)Modify(1,1,N,d);
137                 }
138                 
139                 if(x1<=x&&y1>y){
140                     tx=x1-1;ty=y1;
141                     if(tx)Modify(1,1,N,-d);
142                 }
143                 
144                 if(x1>x&&y1<=y){
145                     tx=x1;ty=y1-1;
146                     if(ty)Modify(1,1,N,-d);
147                 }
148                 
149                 if(x1>x&&y1>y){
150                     tx=x1;ty=y1;
151                     Modify(1,1,N,d);
152                 }
153             }
154             
155             
156             {
157                 if(x1<=x&&y2<y){
158                     tx=x1-1;ty=y2;
159                     if(tx)Modify(1,1,N,-d);
160                 }
161                 
162                 if(x1<=x&&y2>=y){
163                     tx=x1-1;ty=y2+1;
164                     if(tx&&ty<=M)Modify(1,1,N,d);
165                 }
166                 
167                 if(x1>x&&y2<y){
168                     tx=x1;ty=y2;
169                     Modify(1,1,N,d);
170                 }
171                 
172                 if(x1>x&&y2>=y){
173                     tx=x1;ty=y2+1;
174                     if(ty<=M)Modify(1,1,N,-d);
175                 }
176             }
177             
178             {
179                 if(x2<x&&y1<=y){
180                     tx=x2;ty=y1-1;
181                     if(ty)Modify(1,1,N,-d);
182                 }
183                 
184                 if(x2<x&&y1>y){
185                     tx=x2;ty=y1;
186                     Modify(1,1,N,d);
187                 }
188                 
189                 if(x2>=x&&y1<=y){
190                     tx=x2+1;ty=y1-1;
191                     if(tx<=N&&ty)Modify(1,1,N,d);
192                 }
193                 
194                 if(x2>=x&&y1>y){
195                     tx=x2+1;ty=y1;
196                     if(tx<=N)Modify(1,1,N,-d);
197                 }
198             }
199             
200             {
201                 if(x2<x&&y2<y){
202                     tx=x2;ty=y2;
203                     Modify(1,1,N,d);
204                 }
205                 
206                 if(x2<x&&y2>=y){
207                     tx=x2;ty=y2+1;
208                     if(ty<=M)Modify(1,1,N,-d);
209                 }
210                 
211                 if(x2>=x&&y2<y){
212                     tx=x2+1;ty=y2;
213                     if(tx<=N)Modify(1,1,N,-d);
214                 }
215                 
216                 if(x2>=x&&y2>=y){
217                     tx=x2+1;ty=y2+1;
218                     if(tx<=N&&ty<=M)Modify(1,1,N,d);
219                 }
220             }
221             
222             if(x1<=x&&x2>=x){
223                 if(y1<=y){
224                     tx=x;ty=y1-1;
225                     if(ty)Modify(1,1,N,-d);
226                 }
227                 if(y1>y){
228                     tx=x;ty=y1;
229                     Modify(1,1,N,d);
230                 }
231                 
232                 if(y2<y){
233                     tx=x;ty=y2;
234                     Modify(1,1,N,d);
235                 }
236                 if(y2>=y){
237                     tx=x;ty=y2+1;
238                     if(ty<=M)Modify(1,1,N,-d);
239                 }
240             }
241             
242             if(y1<=y&&y2>=y){
243                 if(x1<=x){
244                     tx=x1-1;ty=y;
245                     if(tx)Modify(1,1,N,-d);
246                 }
247                 if(x1>x){
248                     tx=x1;ty=y;
249                     Modify(1,1,N,d);
250                 }
251                 
252                 if(x2<x){
253                     tx=x2;ty=y;
254                     Modify(1,1,N,d);
255                 }
256                 if(x2>=x){
257                     tx=x2+1;ty=y;
258                     if(tx<=N)Modify(1,1,N,-d);
259                 }
260             }
261             
262             if(x1<=x&&x2>=x&&y1<=y&&y2>=y){
263                 tx=x;ty=y;
264                 Modify(1,1,N,d);
265             }
266         }
267     }    
268     return 0;
269 } 

 

posted @ 2016-07-15 22:57  TenderRun  阅读(456)  评论(0编辑  收藏  举报