题目大意:
就是在二维的空间内进行单个的修改,或者进行整块矩形区域的最大最小值查询
二维线段树树,要注意的是第一维上不是叶子形成的第二维线段树和叶子形成的第二维线段树要 不同的处理方式,非叶子形成的线段树总是在自身的叶子处不能直接更新数据,而是要以一维下他的左右孩子对应的位置数据进行更新。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define N 505 4 #define ls o<<1 5 #define rs o<<1|1 6 #define def_m int m=(l+r)>>1 7 const int INF = 0x7fffffff; 8 int n , q , mx[N*3][N*3] , mn[N*3][N*3] , ansmx,ansmn,a[N][N]; 9 void update1D(int o , int l , int r , int y , int ox , int v,int flag) 10 { 11 if(l==r){ 12 if(!flag)mx[ox][o] = mn[ox][o] = v; 13 else{mx[ox][o] = max(mx[ox<<1][o],mx[ox<<1|1][o]) ; mn[ox][o] = min(mn[ox<<1][o],mn[ox<<1|1][o]);} 14 return ; 15 } 16 def_m; 17 if(m>=y) update1D(ls,l,m,y,ox,v,flag); 18 else update1D(rs,m+1,r,y,ox,v,flag); 19 mx[ox][o] = max(mx[ox][ls] , mx[ox][rs]); 20 mn[ox][o] = min(mn[ox][ls] , mn[ox][rs]); 21 // cout<<ox<<" "<<o<<" "<<l<<" "<<r<<" "<<y<<" "<<v<<endl; 22 } 23 void update2D(int o , int l , int r , int x , int y , int v) 24 { 25 // cout<<"v: "<<v<<endl; 26 if(l==r){ 27 update1D(1,1,n,y,o,v,0); 28 return ; 29 } 30 def_m; 31 if(m>=x) update2D(ls,l,m,x,y,v); 32 else update2D(rs,m+1,r,x,y,v); 33 update1D(1,1,n,y,o,v,1); 34 } 35 void query1D(int o , int l , int r , int s , int t , int ox) 36 { 37 if(l>=s&&r<=t){ 38 ansmx=max(ansmx,mx[ox][o]); 39 // cout<<"in query: "<<ox<<" "<<o<<" "<<s<<" "<<t<<" "<<mx[ox][o]<<" "<<mn[ox][o]<<endl; 40 ansmn=min(ansmn,mn[ox][o]); 41 return ; 42 } 43 def_m; 44 if(m>=s) query1D(ls,l,m,s,t,ox); 45 if(m<t) query1D(rs,m+1,r,s,t,ox); 46 } 47 void query2D(int o,int l,int r,int sx,int tx,int sy,int ty) 48 { 49 if(l>=sx&&r<=tx){ 50 query1D(1,1,n,sy,ty,o); 51 return ; 52 } 53 def_m; 54 if(m>=sx) query2D(ls,l,m,sx,tx,sy,ty); 55 if(m<tx) query2D(rs,m+1,r,sx,tx,sy,ty); 56 } 57 void build1D(int o , int l , int r , int ox , int x) 58 { 59 if(l==r){ 60 if(x>=0) mx[ox][o] = mn[ox][o] = a[x][l]; 61 else mx[ox][o] = max(mx[ox<<1][o] , mx[ox<<1|1][o]) , mn[ox][o] = min(mn[ox<<1][o] , mn[ox<<1|1][o]); 62 return ; 63 } 64 def_m; 65 build1D(ls , l , m , ox , x); 66 build1D(rs , m+1 , r , ox , x); 67 mx[ox][o] = max(mx[ox][ls] , mx[ox][rs]); 68 mn[ox][o] = min(mn[ox][ls] , mn[ox][rs]); 69 } 70 void build2D(int o , int l , int r , int ly , int ry) 71 { 72 if(l==r){ 73 build1D(1,1,n,o,l); 74 return ; 75 } 76 def_m; 77 build2D(ls , l , m , ly , ry); 78 build2D(rs , m+1 , r , ly , ry); 79 build1D(1 , 1 , n , o , -1); 80 } 81 int main() 82 { 83 // freopen("a.in" , "r" , stdin); 84 while(~scanf("%d" , &n)){ 85 memset(mx , 0x80 , sizeof(mx)); 86 memset(mn , 0x7f , sizeof(mn)); 87 for(int i=1 ; i<=n ; i++) 88 for(int j=1 ; j<=n ; j++)scanf("%d" , &a[i][j]); 89 90 build2D(1,1,n,1,n); 91 92 scanf("%d" , &q); 93 for(int i=0 ; i<q ; i++){ 94 char op[3]; 95 scanf("%s" , op); 96 if(op[0]=='q'){ 97 int x1,y1,x2,y2; 98 scanf("%d%d%d%d" , &x1,&y1,&x2,&y2); 99 ansmx = -INF , ansmn=INF; 100 query2D(1,1,n,x1,x2,y1,y2); 101 printf("%d %d " , ansmx,ansmn); 102 } 103 else{ 104 int x,y,v; 105 scanf("%d%d%d" , &x,&y,&v); 106 update2D(1,1,n,x,y,v); 107 } 108 } 109 } 110 return 0; 111 }