【题解】P4114 Qtree1

P4114】题解

题意

  • 给定一个带边权的树
  • 有两个操作
  • 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;
}
posted @ 2025-12-06 18:46  Ming3398  阅读(3)  评论(0)    收藏  举报