poj3237 Tree

树链剖分基本操作:

1. 修改第i条边的权值。

2. 对树上一条路径的权值取反(正变负,负变正)。

3. 查询树上一条路径的权值的最大值。

因为要取反,所以要同时维护最大值和最小值。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define lson l,mid,rt<<1
  5 #define rson mid+1,r,rt<<1|1
  6 using namespace std;
  7 
  8 const int N=1e4+10;
  9 const int M=2e4+10;
 10 const int inf=0x3f3f3f3f;
 11 
 12 int head[N],to[M],nxt[M],w[M],kk[M];//kk:边的编号 
 13 int tot;
 14 int dep[N],fa[N],siz[N],son[N],idx[N];//idx:每个点与它的父亲之间的边的编号 
 15 int top[N],id[N],wt[N];
 16 int cnt;
 17 int mx[N<<2],mi[N<<2],tag[N<<2];
 18 int num[N];//第x条边(按输入顺序)的新编号 
 19 int n;
 20 
 21 inline void add(int u,int v,int x,int i){
 22     to[++tot]=v,nxt[tot]=head[u],w[tot]=x,kk[tot]=i,head[u]=tot;
 23 }
 24 
 25 void dfs1(int u,int f){
 26     dep[u]=dep[f]+1;
 27     fa[u]=f;
 28     siz[u]=1;
 29     int maxs=-1;
 30     for(int i=head[u];i;i=nxt[i]){
 31         int v=to[i];
 32         if(v==f) continue;
 33         dfs1(v,u);
 34         siz[u]+=siz[v];
 35         idx[v]=i;
 36         if(siz[v]>maxs) maxs=siz[v],son[u]=v;
 37     }
 38 }
 39 
 40 void dfs2(int u,int topf){
 41     id[u]=++cnt;
 42     wt[cnt]=w[idx[u]];
 43     top[u]=topf;
 44     num[kk[idx[u]]]=cnt;
 45     if(!son[u]) return;
 46     dfs2(son[u],topf);
 47     for(int i=head[u];i;i=nxt[i]){
 48         int v=to[i];
 49         if(v==fa[u]||v==son[u]) continue;
 50         dfs2(v,v);
 51     }
 52 }
 53 
 54 inline void push_up(int rt){
 55     mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
 56     mi[rt]=min(mi[rt<<1],mi[rt<<1|1]);
 57 }
 58 
 59 inline void push_down(int rt){
 60     if(tag[rt]){
 61         int tmp=mx[rt<<1];
 62         mx[rt<<1]=-mi[rt<<1];
 63         mi[rt<<1]=-tmp;
 64         tmp=mx[rt<<1|1];
 65         mx[rt<<1|1]=-mi[rt<<1|1];
 66         mi[rt<<1|1]=-tmp;
 67         tag[rt<<1]^=1; tag[rt<<1|1]^=1;
 68         tag[rt]=0;
 69     }
 70 }
 71 
 72 void build(int l,int r,int rt){
 73     tag[rt]=0;
 74     if(l==r){
 75         mx[rt]=mi[rt]=wt[l];
 76         return;
 77     }
 78     int mid=(l+r)>>1;
 79     build(lson),build(rson);
 80     push_up(rt);
 81 }
 82 
 83 void update1(int x,int z,int l,int r,int rt){
 84     if(l==r){
 85         mx[rt]=mi[rt]=z;
 86         return;
 87     }
 88     push_down(rt);
 89     int mid=(l+r)>>1;
 90     if(x<=mid) update1(x,z,lson);
 91     if(x>mid) update1(x,z,rson);
 92     push_up(rt);
 93 }
 94 
 95 void update2(int x,int y,int l,int r,int rt){
 96     if(x<=l&&y>=r){
 97         int tmp=mx[rt];
 98         mx[rt]=-mi[rt];
 99         mi[rt]=-tmp;
100         tag[rt]^=1;
101         return;
102     }
103     push_down(rt);
104     int mid=(l+r)>>1;
105     if(x<=mid) update2(x,y,lson);
106     if(y>mid) update2(x,y,rson);
107     push_up(rt);
108 }
109 
110 int query(int x,int y,int l,int r,int rt){
111     if(x<=l&&y>=r) return mx[rt];
112     push_down(rt);
113     int ans=-inf;
114     int mid=(l+r)>>1;
115     if(x<=mid) ans=max(ans,query(x,y,lson));
116     if(y>mid) ans=max(ans,query(x,y,rson));
117     return ans;
118 }
119 
120 inline void uprange1(int x,int z){
121     update1(num[x],z,1,n,1);
122 }
123 
124 void uprange2(int x,int y){
125     while(top[x]!=top[y]){
126         if(dep[top[x]]<dep[top[y]]) swap(x,y);
127         update2(id[top[x]],id[x],1,n,1);
128         x=fa[top[x]];
129     }
130     if(x==y) return;
131     if(dep[x]>dep[y]) swap(x,y);
132     update2(id[x]+1,id[y],1,n,1);
133 }
134 
135 int qrange(int x,int y){
136     int ans=-inf;
137     while(top[x]!=top[y]){
138         if(dep[top[x]]<dep[top[y]]) swap(x,y);
139         ans=max(ans,query(id[top[x]],id[x],1,n,1));
140         x=fa[top[x]];
141     }
142     if(x==y) return ans;
143     if(dep[x]>dep[y]) swap(x,y);
144     return max(ans,query(id[x]+1,id[y],1,n,1));
145 }
146 
147 void init(){
148     tot=cnt=0;
149     memset(head,0,sizeof(head));
150     memset(son,0,sizeof(son));
151 }
152 
153 int main()
154 {
155     int T;
156     char ch[10];
157     scanf("%d",&T);
158     while(T--){
159         init();
160         scanf("%d",&n);
161         for(int i=1;i<n;i++){
162             int u,v,x;
163             scanf("%d%d%d",&u,&v,&x);
164             add(u,v,x,i);
165             add(v,u,x,i);
166         }
167         dfs1(1,0); dfs2(1,1);
168         build(1,n,1);
169         while(~scanf("%s",ch)){
170             if(ch[0]=='D') break;
171             if(ch[0]=='C'){
172                 int x,z;
173                 scanf("%d%d",&x,&z);
174                 uprange1(x,z);
175             }
176             else if(ch[0]=='N'){
177                 int x,y;
178                 scanf("%d%d",&x,&y);
179                 uprange2(x,y);
180             }
181             else{
182                 int x,y;
183                 scanf("%d%d",&x,&y);
184                 printf("%d
",qrange(x,y));
185             }
186         }
187     }
188     return 0;
189 }
原文地址:https://www.cnblogs.com/--HY--/p/13511474.html