http://acm.hdu.edu.cn/showproblem.php?pid=4819
给出一个N*N的矩阵,每次询问一个m*m的子矩阵里的floor((maxv+minv)/2)并把中间的元素修改为这个值。
线段树套线段树,第一层X表示对行建立的线段树,内层表示对Y也就是列建立的线段树。
分别对X和Y建立相应的函数来完成操作,当更新X树的节点时,再更新完当前X的节点的左右儿子之后,回头对X的这个节点对应的Y树进行更新,相当于X的左右儿子里的Y树来更新X的Y树,能理解这一点就很简单了。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pii pair<int,int> 4 #define mp make_pair 5 #define LL long long 6 #define lc (id<<1) 7 #define rc (id<<1|1) 8 #define flc (fid<<1) 9 #define frc (fid<<1|1) 10 #define mid ((L+R)>>1) 11 const int maxn=810; 12 int maxv[maxn<<2][maxn<<2]; 13 int minv[maxn<<2][maxn<<2]; 14 int a[maxn][maxn],N,x1,x2,y1,y2; 15 void buildY(int,int,int,int,int,int); 16 void buildX(int id,int L,int R){ 17 if(L==R){ 18 buildY(id,L,R,1,1,N); 19 } 20 else{ 21 buildX(lc,L,mid); 22 buildX(rc,mid+1,R); 23 buildY(id,L,R,1,1,N); 24 } 25 } 26 void buildY(int fid,int fl,int fr,int id,int L,int R){ 27 if(L==R){ 28 if(fl==fr)maxv[fid][id]=minv[fid][id]=a[fl][L]; 29 else{ 30 maxv[fid][id]=max(maxv[flc][id],maxv[frc][id]); 31 minv[fid][id]=min(minv[flc][id],minv[frc][id]); 32 } 33 } 34 else{ 35 buildY(fid,fl,fr,lc,L,mid); 36 buildY(fid,fl,fr,rc,mid+1,R); 37 maxv[fid][id]=max(maxv[fid][lc],maxv[fid][rc]); 38 minv[fid][id]=min(minv[fid][lc],minv[fid][rc]); 39 } 40 } 41 pii askY(int fid,int id,int L,int R){ 42 if(L>=y1&&R<=y2){ 43 return mp(maxv[fid][id],minv[fid][id]); 44 } 45 else{ 46 if(y2<=mid) return askY(fid,lc,L,mid); 47 else if(y1>mid) return askY(fid,rc,mid+1,R); 48 else{ 49 pii pl=askY(fid,lc,L,mid), 50 pr=askY(fid,rc,mid+1,R); 51 return mp(max(pl.first,pr.first),min(pl.second,pr.second)); 52 } 53 } 54 } 55 pii askX(int id,int L,int R){ 56 if(L>=x1&&R<=x2){ 57 return askY(id,1,1,N); 58 } 59 else{ 60 if(x2<=mid) return askX(lc,L,mid); 61 else if(x1>mid) return askX(rc,mid+1,R); 62 else{ 63 pii pl=askX(lc,L,mid), 64 pr=askX(rc,mid+1,R); 65 return mp(max(pl.first,pr.first),min(pl.second,pr.second)); 66 } 67 } 68 } 69 void updateY(int fid,int fl,int fr,int id,int L,int R,int x,int y,int v){ 70 if(L==R){ 71 if(fl==fr){ 72 maxv[fid][id]=minv[fid][id]=v; 73 } 74 else{ 75 maxv[fid][id]=max(maxv[flc][id],maxv[frc][id]); 76 minv[fid][id]=min(minv[flc][id],minv[frc][id]); 77 } 78 } 79 else{ 80 if(y<=mid){ 81 updateY(fid,fl,fr,lc,L,mid,x,y,v); 82 } 83 else{ 84 updateY(fid,fl,fr,rc,mid+1,R,x,y,v); 85 } 86 maxv[fid][id]=max(maxv[fid][lc],maxv[fid][rc]); 87 minv[fid][id]=min(minv[fid][lc],minv[fid][rc]); 88 } 89 } 90 void updateX(int id,int L,int R,int x,int y,int v){ 91 if(L==R){ 92 updateY(id,L,R,1,1,N,x,y,v); 93 } 94 else{ 95 if(x<=mid) updateX(lc,L,mid,x,y,v); 96 else updateX(rc,mid+1,R,x,y,v); 97 updateY(id,L,R,1,1,N,x,y,v); 98 } 99 } 100 int main() 101 { 102 int T,M,i,j,x,y,d; 103 scanf("%d",&T); 104 for(int cas=1;cas<=T;++cas){ 105 scanf("%d",&N); 106 for(i=1;i<=N;++i){ 107 for(j=1;j<=N;++j){ 108 scanf("%d",&a[i][j]); 109 } 110 } 111 buildX(1,1,N); 112 scanf("%d",&M); 113 printf("Case #%d: ",cas); 114 while(M--){ 115 scanf("%d%d%d",&x,&y,&d); 116 x1=x-d/2,x2=x+d/2,y1=y-d/2,y2=y+d/2; 117 x1=max(x1,1),x2=min(x2,N); 118 y1=max(y1,1),y2=min(y2,N); 119 pii ans=askX(1,1,N); 120 updateX(1,1,N,x,y,(ans.first+ans.second)/2); 121 printf("%d ",(ans.first+ans.second)/2); 122 } 123 } 124 return 0; 125 }