[POJ3237]Tree

Posted

tags:

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

仍然是树剖模板题TT

线段树维护取反和最大值就同时维护最大最小值,取反时最大最小值取反交换即可

单点修改时记得把叶节点的lazy tag置0

 

  1 #include<stdio.h>
  2 int h[10010],nex[20010],va[10010],vb[10010],ev[20010],to[20010],v[10010],siz[10010],son[10010],fa[10010],dep[10010],bl[10010],pos[10010],tot,sz,M,Tmin[40010],Tmax[40010],laz[40010];
  3 void add(int a,int b,int v){
  4     tot++;
  5     to[tot]=b;
  6     ev[tot]=v;
  7     nex[tot]=h[a];
  8     h[a]=tot;
  9 }
 10 void dfs(int x){
 11     siz[x]=1;
 12     int mx=0,k=0,i;
 13     for(i=h[x];i;i=nex[i]){
 14         if(to[i]!=fa[x]){
 15             fa[to[i]]=x;
 16             v[to[i]]=ev[i];
 17             dep[to[i]]=dep[x]+1;
 18             dfs(to[i]);
 19             siz[x]+=siz[to[i]];
 20             if(siz[to[i]]>mx){
 21                 mx=siz[to[i]];
 22                 k=to[i];
 23             }
 24         }
 25     }
 26     son[x]=k;
 27 }
 28 void dfs(int x,int chain){
 29     bl[x]=chain;
 30     sz++;
 31     pos[x]=sz;
 32     if(son[x])dfs(son[x],chain);
 33     for(int i=h[x];i;i=nex[i]){
 34         if(to[i]!=fa[x]&&to[i]!=son[x])dfs(to[i],to[i]);
 35     }
 36 }
 37 void pushdown(int x){
 38     if(laz[x]){
 39         int t=Tmin[x<<1];
 40         Tmin[x<<1]=-Tmax[x<<1];
 41         Tmax[x<<1]=-t;
 42         t=Tmin[x<<1|1];
 43         Tmin[x<<1|1]=-Tmax[x<<1|1];
 44         Tmax[x<<1|1]=-t;
 45         laz[x]=0;
 46         laz[x<<1]^=1;
 47         laz[x<<1|1]^=1;
 48     }
 49 }
 50 int min(int a,int b){return a<b?a:b;}
 51 int max(int a,int b){return a>b?a:b;}
 52 void pushup(int x){
 53     Tmin[x]=min(Tmin[x<<1],Tmin[x<<1|1]);
 54     Tmax[x]=max(Tmax[x<<1],Tmax[x<<1|1]);
 55 }
 56 void modify(int L,int R,int l,int r,int x){
 57     if(L<=l&&r<=R){
 58         laz[x]^=1;
 59         l=Tmin[x];
 60         Tmin[x]=-Tmax[x];
 61         Tmax[x]=-l;
 62         return;
 63     }
 64     pushdown(x);
 65     int mid=(l+r)>>1;
 66     if(L<=mid)modify(L,R,l,mid,x<<1);
 67     if(R>mid)modify(L,R,mid+1,r,x<<1|1);
 68     pushup(x);
 69 }
 70 void swap(int&a,int&b){a^=b^=a^=b;}
 71 void modify(int x,int y){
 72     while(bl[x]!=bl[y]){
 73         if(dep[bl[x]]<dep[bl[y]])swap(x,y);
 74         modify(pos[bl[x]],pos[x],1,M,1);
 75         x=fa[bl[x]];
 76     }
 77     if(x==y)return;
 78     if(pos[x]>pos[y])swap(x,y);
 79     modify(pos[x]+1,pos[y],1,M,1);
 80 }
 81 int querymax(int L,int R,int l,int r,int x){
 82     if(L<=l&&r<=R)return Tmax[x];
 83     pushdown(x);
 84     int mid=(l+r)>>1,ans=-2147483647;
 85     if(L<=mid)ans=max(ans,querymax(L,R,l,mid,x<<1));
 86     if(R>mid)ans=max(ans,querymax(L,R,mid+1,r,x<<1|1));
 87     return ans;
 88 }
 89 int getmax(int x,int y){
 90     int ans=-1061109567;
 91     while(bl[x]!=bl[y]){
 92         if(dep[bl[x]]<dep[bl[y]])swap(x,y);
 93         ans=max(ans,querymax(pos[bl[x]],pos[x],1,M,1));
 94         x=fa[bl[x]];
 95     }
 96     if(x==y)return ans;
 97     if(pos[x]>pos[y])swap(x,y);
 98     return max(ans,querymax(pos[x]+1,pos[y],1,M,1));
 99 }
100 void modifys(int pos,int v,int l,int r,int x){
101     if(l==r){
102         Tmax[x]=Tmin[x]=v;
103         laz[x]=0;
104         return;
105     }
106     pushdown(x);
107     int mid=(l+r)>>1;
108     if(pos<=mid)
109         modifys(pos,v,l,mid,x<<1);
110     else
111         modifys(pos,v,mid+1,r,x<<1|1);
112     pushup(x);
113 }
114 int main(){
115     int t,i,n,a,b;
116     char s[10];
117     scanf("%d",&t);
118     while(t--){
119         scanf("%d",&n);
120         tot=sz=0;
121         for(i=1;i<=n;i++)h[i]=0;
122         for(i=1;i<n;i++){
123             scanf("%d%d%d",va+i,vb+i,&a);
124             add(va[i],vb[i],a);
125             add(vb[i],va[i],a);
126         }
127         dfs(1);
128         dfs(1,1);
129         for(M=1;M<n+2;M<<=1);
130         for(i=0;i<(M<<1);i++){
131             Tmax[i]=-2147483647;
132             Tmin[i]=2147483647;
133             laz[i]=0;
134         }
135         for(i=1;i<=n;i++)Tmax[pos[i]+M-1]=Tmin[pos[i]+M-1]=v[i];
136         for(i=M-1;i>0;i--)pushup(i);
137         scanf("%s",s);
138         while(s[0]!=D){
139             scanf("%d%d",&a,&b);
140             if(s[0]==Q)printf("%d\n",getmax(a,b));
141             if(s[0]==N)modify(a,b);
142             if(s[0]==C){
143                 if(fa[va[a]]==vb[a])
144                     modifys(pos[va[a]],b,1,M,1);
145                 else
146                     modifys(pos[vb[a]],b,1,M,1);
147             }
148             scanf("%s",s);
149         }
150     }
151 }

 

以上是关于[POJ3237]Tree的主要内容,如果未能解决你的问题,请参考以下文章

POJ3237Tree 树链剖分+线段树

poj3237 Tree

●POJ 3237 Tree

poj 3237 Tree(树链剖分,线段树)

[POJ3237]Tree

POJ 3237 (Tree)