题目链接:传送门
题目大意:给一棵树,三种操作,query询问 a ~ b 路径上最大边权值,change改变按输入顺序的第 a 条边的
边权为 b,negate将 a~b路径上的边权值取相反数。
题目思路:树链剖分,取相反数直接更新到底就行,不用延迟标记,若非要延迟的话,则线段树需保存最大值和
最小值。每次取反就将他俩交换并分别取反。
1 #include <iostream>
2 #include <cstdio>
3 #include <cstdlib>
4 #include <cmath>
5 #include <algorithm>
6 #include <cstring>
7 #include <stack>
8 #include <cctype>
9 #include <queue>
10 #include <string>
11 #include <vector>
12 #include <set>
13 #include <map>
14 #include <climits>
15 #define lson rt<<1,l,mid
16 #define rson rt<<1|1,mid+1,r
17 #define fi first
18 #define se second
19 #define ping(x,y) ((x-y)*(x-y))
20 #define mst(x,y) memset(x,y,sizeof(x))
21 #define mcp(x,y) memcpy(x,y,sizeof(y))
22 using namespace std;
23 #define gamma 0.5772156649015328606065120
24 #define MOD 1000000007
25 #define inf 0x3f3f3f3f
26 #define N 100005
27 #define maxn 30010
28 typedef pair<int,int> PII;
29 typedef long long LL;
30 LL read(){
31 LL x=0,f=1;char ch=getchar();
32 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
33 while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
34 return x*f;
35 }
36 int n,m,k,sz,L,R,pre,pre2,nowr,nowl;
37 int son[N],siz[N],top[N],fa[N];
38 int dep[N],posi[N],id[N],tid;
39 int seg[N<<2],mrk[N<<2];
40 char str[1111];
41 struct Edge{
42 int x,y,v;
43 }edge[N];
44 struct Node{
45 int to,nxt;
46 }node[N<<1];int head[N],hcnt;
47
48 void dfs1(int u,int f,int deep){
49 dep[u]=deep;siz[u]=1;fa[u]=f;
50 for(int i=head[u];~i;i=node[i].nxt){
51 int e=node[i].to;
52 if(e==f)continue;
53 dfs1(e,u,deep+1);
54 siz[u]+=siz[e];
55 if(!son[u]||siz[son[u]]<siz[e])
56 son[u]=e;
57 }
58 }
59 void dfs2(int u,int tp){
60 top[u]=tp,id[u]=++tid;
61 if(!son[u])return;
62 dfs2(son[u],tp);
63 for(int i=head[u];~i;i=node[i].nxt){
64 int e=node[i].to;
65 if(id[e])continue;
66 dfs2(e,e);
67 }
68 }
69 void update(int rt,int l,int r,int v){
70 if(l==r){
71 if(v==inf)seg[rt]=-seg[rt];
72 else seg[rt]=v;
73 return;
74 }
75 int mid=l+r>>1;
76 if(L<=mid)update(lson,v);
77 if(R>mid) update(rson,v);
78 seg[rt]=max(seg[rt<<1],seg[rt<<1|1]);
79 }
80 int query(int rt,int l,int r){
81 if(L<=l&&r<=R)return seg[rt];
82 int temp=INT_MIN,mid=l+r>>1;
83 if(L<=mid)temp=max(temp,query(lson));
84 if(R>mid) temp=max(temp,query(rson));
85 seg[rt]=max(seg[rt<<1],seg[rt<<1|1]);
86 return temp;
87 }
88 void init(){
89 mst(head,-1);tid=hcnt=0;
90 mst(id,0);mst(son,0);mst(siz,0);
91 mst(mrk,0);
92 }
93 void change(int x,int y,int flag){
94 if(!flag){
95 L=id[edge[x].x],R=id[edge[x].x];
96 update(1,1,n,y);
97 }
98 else{
99 while(top[x]!=top[y]){
100 if(dep[top[x]]<dep[top[y]])swap(x,y);
101 L=id[top[x]],R=id[x];
102 update(1,1,n,inf);
103 x=fa[top[x]];
104 }
105 if(dep[x]>dep[y])swap(x,y);
106 L=id[x]+1,R=id[y];
107 update(1,1,n,inf);
108 }
109 }
110 int lca(int x,int y){
111 int res=INT_MIN;
112 while(top[x]!=top[y]){
113 if(dep[top[x]]<dep[top[y]])swap(x,y);
114 L=id[top[x]],R=id[x];
115 res=max(res,query(1,1,n));
116 x=fa[top[x]];
117 }
118 if(dep[x]>dep[y])swap(x,y);
119 L=id[x]+1,R=id[y];
120 if(x!=y)res=max(res,query(1,1,n));
121 return res;
122 }
123 int main(){
124 int i,j,group,x,y,v;
125 group=read();
126 while(group--){
127 init();
128 n=read();
129 for(i=1;i<n;++i){
130 x=read(),y=read(),v=read();
131 edge[i].x=x,edge[i].y=y,edge[i].v=v;
132 node[hcnt].to=y,node[hcnt].nxt=head[x],head[x]=hcnt++;
133 node[hcnt].to=x,node[hcnt].nxt=head[y],head[y]=hcnt++;
134 }
135 dfs1(1,1,1);dfs2(1,1);
136 for(i=1;i<n;++i){
137 if(dep[edge[i].x]<dep[edge[i].y])swap(edge[i].x,edge[i].y);
138 L=id[edge[i].x],R=id[edge[i].x];
139 update(1,1,n,edge[i].v);
140 }
141 while(scanf("%s",str)!=EOF){
142 if(str[0]=='D')break;
143 x=read(),y=read();
144 if(str[0]=='Q') printf("%d\n",lca(x,y));
145 else if(str[0]=='C') change(x,y,0);
146 else change(x,y,1);
147 }
148 }
149 return 0;
150 }
来源:https://www.cnblogs.com/Kurokey/p/5920908.html