题意
- 给定一个带边权的树
- 有两个操作
- 1.修改某条边的边权
- 2.查询a->b的路径上的边权最大值
分析
- 边权转为dep较深的点的点权
- 树剖板子
- 最后注意改为query(dfn[u]+1,dfn[v])就可以了
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct Edge{
int a,b,c;
}edg[N];
vector<int> mp[N];
int nod[N];
int nw[N];
void regraph(int u,int fa){
for(auto e:mp[u]){
int v;
if(u==edg[e].b) v=edg[e].a;
else v=edg[e].b;
if(v==fa) continue;
nod[e]=v;
nw[v]=edg[e].c;
regraph(v,u);
}
}
int siz[N],dep[N],son[N],fa[N];
void Son(int u,int pa){
fa[u]=pa;
siz[u]=1;
dep[u]=dep[pa]+1;
for(auto v:mp[u]){
if(v==pa) continue;
Son(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]]) son[u]=v;
}
}
int top[N],dfn[N],cnt;
int a[N];
void Line(int u,int tp){
dfn[u]=++cnt;
a[cnt]=nw[u];
top[u]=tp;
if(!son[u]) return ;
Line(son[u],tp);
for(auto v:mp[u]){
if(v==fa[u]||v==son[u]) continue;
Line(v,v);
}
}
struct line_tree{
struct node{
int l,r,maxn;
#define l(q) tree[q].l
#define r(q) tree[q].r
#define maxn(q) tree[q].maxn
}tree[N<<2];
void push_up(int q){
maxn(q)=max(maxn(q<<1),maxn(q<<1|1));
}
void build(int q,int l,int r){
l(q)=l;r(q)=r;
if(l==r){
maxn(q)=a[l];
return ;
}
int mid=l+r>>1;
build(q<<1,l,mid);
build(q<<1|1,mid+1,r);
push_up(q);
}
void update(int q,int tp,int d){
int l=l(q),r=r(q);
if(l==r){
maxn(q)=d;
return ;
}
int mid=l+r>>1;
if(tp<=mid) update(q<<1,tp,d);
else update(q<<1|1,tp,d);
push_up(q);
}
int query(int q,int L,int R){
int l=l(q),r=r(q);
if(L<=l&&r<=R){
return maxn(q);
}
int mid=l+r>>1;
int res=0;
if(L<=mid) res=max(res,query(q<<1,L,R));
if(mid<R) res=max(res,query(q<<1|1,L,R));
return res;
}
}lt;
void update(int x,int d){
lt.update(1,x,d);
}
int query(int x,int y){
int res=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
res=max(res,lt.query(1,dfn[top[x]],dfn[x]));
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
if(x!=y) res=max(res,lt.query(1,dfn[x]+1,dfn[y]));
return res;
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n;cin>>n;
for(int i=1;i<n;i++){
int a,b,c;cin>>a>>b>>c;
edg[i]={a,b,c};
mp[a].push_back(i);
mp[b].push_back(i);
}
//重构图
regraph(1,1);
for(int i=1;i<=n;i++) mp[i].clear();
for(int i=1;i<n;i++){
int a=edg[i].a,b=edg[i].b;
mp[a].push_back(b);
mp[b].push_back(a);
}
//重构图
Son(1,1);
Line(1,1);
lt.build(1,1,n);
while(1){
string s;cin>>s;
if(s=="DONE") break;
else if(s=="CHANGE"){
int x,t;cin>>x>>t;
x=nod[x];
update(dfn[x],t);
}
else{
int a,b;cin>>a>>b;
cout<<query(a,b)<<"\n";
}
}
return 0;
}