POJ3237 树的维护

P1424 - [POJ3237]树的维护

Description

给你由N个结点组成的树。树的节点被编号为1到N,边被编号为1到N-1。每一条边有一个权值。然后你要在树上执行一系列指令。指令可以是如下三种之一:
CHANGE i v:将第i条边的权值改成v。
NEGATE a b:将点a到点b路径上所有边的权值变成其相反数。
QUERY a b:找出点a到点b路径上各边的最大权值。

Input

第一行有一个整数N(N<=10000)。
接下来N-1行每行有三个整数a,b,c,代表点a和点b之间有一条权值为c的边。这些边按照其编号从小到大给出。
接下来是若干条指令(不超过10^5条),都按照上面所说的格式。
最后一行是"DONE".

Output

对每个“QUERY”指令,输出一行,即路径上各边的最大权值。

Sample Input

3
1 2 1
2 3 2
QUERY 1 2
CHANGE 1 3
QUERY 1 2
DONE

Sample Output

1
3

Hint

Source

POJ 3237 Tree
树链剖分, 动态树, LCA

 

线段树,TMD调了我一个晚上+半个上午,最后才知道是因为lazy标记没有下放,woc

  1 #define ls o*2
  2 #define rs o*2+1
  3 
  4 #define inf 1999999999
  5 #include<algorithm>
  6 #include<iostream>
  7 #include<iomanip>
  8 #include<cstring>
  9 #include<cstdlib>
 10 #include<cstdio>
 11 #include<queue>
 12 #include<ctime>
 13 #include<cmath>
 14 #include<stack>
 15 #include<map>
 16 #include<set>
 17 using namespace std;
 18 const int N=10010,M=N-1;
 19 struct E{
 20     int to,net,w;
 21     int fr;
 22 }e[M*2];
 23 struct TREE{
 24     int bj,Max,Min;
 25     TREE(){
 26     bj=1;
 27     }
 28 }tr[N*4];
 29 int head[N],n,num_e;
 30 void add(int x,int y,int w) {
 31     e[++num_e].to=y;e[num_e].net=head[x];head[x]=num_e;e[num_e].w=w;e[num_e].fr=x;
 32 }
 33 void down(int);
 34 int dep[N],top[N],son[N],tid[N],pos[N],fa[N],siz[N],val[N],idx;
 35 int W[N],len[N*4];
 36 int B[M*2];
 37 void dfs1(int x,int fu) {
 38     siz[x]=1;
 39     dep[x]=dep[fu]+1;//
 40     son[x]=0;
 41     fa[x]=fu;//  meinong
 42     for(int i=head[x];i;i=e[i].net) {
 43     int to=e[i].to;
 44         if(to!=fu) {
 45         val[to]=e[i].w;
 46         dfs1(to,x);
 47         siz[x] += siz[to];//  这一步竟然忘了!!!! 
 48         if(siz[to]>siz[son[x]]) son[x]=to;
 49 //        printf("x=%d son=%d",x,son[x]);P
 50         }
 51     }
 52 }
 53 void dfs2(int x,int tp) {
 54     tid[x]=++idx;
 55     pos[idx]=x;
 56     top[x]=tp;
 57     W[idx]=val[x];//
 58     if(son[x]==0) return;
 59     dfs2(son[x],tp);
 60     for(int i=head[x];i;i=e[i].net)
 61     if(e[i].to!=son[x]&&dep[e[i].to]>dep[x]) {
 62         dfs2(e[i].to,e[i].to);
 63     }
 64 }
 65 void build(int o,int L,int R) {
 66     if(L==R) {
 67     if(L==1) tr[o].Max=-inf,tr[o].Min=inf;
 68      else 
 69       tr[o].Max=W[L],tr[o].Min=W[L];
 70     return;
 71     }
 72     int mid=(L+R)>>1;
 73     build(ls,L,mid);
 74     build(rs,mid+1,R);
 75     tr[o].Max=max(tr[ls].Max,tr[rs].Max);
 76     tr[o].Min=min(tr[ls].Min,tr[rs].Min);
 77 }
 78 void Update(int o,int L,int R,int p,int x) {
 79     if(L!=R) down(o);
 80     if(p==L&&R==p) {
 81     tr[o].Max=x;tr[o].Min=x;
 82     return;
 83     }
 84     int mid=(L+R)>>1;
 85     if(p<=mid) Update(ls,L,mid,p,x);
 86     else Update(rs,mid+1,R,p,x);
 87     tr[o].Max=max(tr[ls].Max,tr[rs].Max);
 88     tr[o].Min=min(tr[ls].Min,tr[rs].Min);
 89 }
 90 void GG(int,int,int,int,int);
 91 //  GG Update()
 92 void solveG(int x,int y) {
 93     while(top[x]!=top[y]) {
 94         if(dep[top[x]]>dep[top[y]]) swap(x,y);
 95         GG(1,1,n,tid[top[y]],tid[y]);
 96         y=fa[top[y]];
 97     }
 98     if(dep[x]>dep[y]) swap(x,y);
 99     if(x==y) return;//  y
100     GG(1,1,n,tid[x]+1,tid[y]);
101 }
102 void down(int o) {
103     int mi;
104     int k=tr[o].bj;
105     if(tr[o].bj==1) return;
106     mi=tr[ls].Min;tr[ls].Min=k*tr[ls].Max,tr[ls].Max=mi*k;//mi
107     mi=tr[rs].Min;tr[rs].Min=k*tr[rs].Max,tr[rs].Max=k*mi;
108     tr[o].bj=1;//复原 //  tr[o].bj==1
109     tr[ls].bj*=-1;
110     tr[rs].bj*=-1;//
111     return;
112 }
113 int querymax(int o,int L,int R,int l,int r) {
114     if(L!=R) down(o);
115     if(l<=L&&R<=r) {
116     return tr[o].Max;
117     }
118     int Max=-inf;
119     int mid=(L+R)>>1;
120     if(l<=mid) Max=max(Max,querymax(ls,L,mid,l,r));
121     if(r>mid) Max=max(Max,querymax(rs,mid+1,R,l,r));
122     return Max;
123 }
124 
125 void GG(int o,int L,int R,int l,int r) {
126     if(L!=R) down(o);
127     if(l<=L&&R<=r) {
128         int mi=tr[o].Min,ma=tr[o].Max;
129         //    tr[o].bj*=-1;
130         tr[o].bj=-1;
131         tr[o].Min=-ma;tr[o].Max=-mi;
132         return;
133     }
134     int mid=(L+R)>>1;
135     if(l<=mid) GG(ls,L,mid,l,r);
136     if(r>mid) GG(rs,mid+1,R,l,r);
137     tr[o].Max=max(tr[ls].Max,tr[rs].Max);
138     tr[o].Min=min(tr[ls].Min,tr[rs].Min);
139 }
140 int solvemax(int x,int y) {
141     int Max=-inf;
142     
143     while(top[x]!=top[y]) {
144     if(dep[top[x]]>dep[top[y]]) swap(x,y);
145     Max=max(Max,querymax(1,1,n,tid[top[y]],tid[y]));
146         y=fa[top[y]];
147     }
148     if(dep[x]>dep[y]) swap(x,y);
149     if(x==y) return Max;
150     Max=max(Max,querymax(1,1,n,tid[x]+1,tid[y]));
151     return Max;
152 }
153 int main() {        
154 
155     cin>>n;int i;
156     for(i=1;i<n;i++) {
157         int x,y,w;scanf("%d%d%d",&x,&y,&w);
158         add(x,y,w);
159         B[i]=num_e;
160         add(y,x,w);
161         }
162         dfs1(1,0);
163         dfs2(1,1);
164         for(i=1;i<n;i++) {
165              int x=e[B[i]].fr,y=e[B[i]].to;
166              if(dep[x]<dep[y]) B[i]=y;
167              else B[i]=x;
168         }
169         build(1,1,n);
170         string s;
171         while(1) {
172         cin>>s;
173         int a,b;scanf("%d%d",&a,&b);
174         if(s[0]=='D') break;
175         else if(s[0]=='C') {
176             a=B[a];
177             Update(1,1,n,tid[a],b);
178         }
179         else if(s[0]=='N') {
180             solveG(a,b);
181            }    
182         else printf("%d\n",solvemax(a,b));
183     }
184     return 0;
185 }
View Code

 

posted @ 2017-03-26 10:10  Yinpz_23  阅读(166)  评论(0编辑  收藏  举报