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
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 }