hdu-4819-线段树套线段树

Posted zzqc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu-4819-线段树套线段树相关的知识,希望对你有一定的参考价值。

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 }

 

以上是关于hdu-4819-线段树套线段树的主要内容,如果未能解决你的问题,请参考以下文章

#树套树,二维线段树#HDU 4819 Mosaic

HDU-4819-Mosaic(二维线段树)

hdu 4819 二维线段树模板

HDU4819 Mosaic树套树

权值线段树套序列线段树

[模板]洛谷T3380 二逼平衡树 线段树套Splay