10pts求调
查看原帖
10pts求调
697161
qwerty111111楼主2024/9/18 15:55
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 10;
int n , m;

int A[N];
int h[N] , tot;
struct node{
	int to , nxt , dis;
} e[N << 1];

inline void add(int u , int v , int w){
	e[++tot].to = v;
	e[tot].nxt = h[u];
	e[tot].dis = w;
	h[u] = tot;
}

int fa[N] , sze[N] , dep[N] , hson[N];
inline void dfs(int x , int f){
	dep[x] = dep[f] + 1 , sze[x] = 1 , hson[x] = 0 , fa[x] = f;
	for (int i = h[x] ; i ; i = e[i].nxt){
		int y = e[i].to;
		if(y == f) continue;
		dfs(y , x);
		sze[x] += sze[y];
		if(sze[hson[x]] < sze[y]) hson[x] = y;
	}
}

int top[N] , dfn[N] , id[N] , cnt;
inline void hld(int x , int topf){
	dfn[x] = ++cnt , id[cnt] = x , top[x] = topf;
	if(hson[x]) hld(hson[x] , topf);
	else return;
	for (int i = h[x] ; i ; i = e[i].nxt){
		int y = e[i].to , w = e[i].dis;
		if(y == fa[x]) continue;
		if(y != hson[x]) hld(y , y);
		A[dfn[y]] = w;
	}
}

namespace SegmentTree{
#define lc (u << 1)
#define rc (u << 1 | 1)
#define mid ((l + r) >> 1)
	int T[N << 2] , tag[N << 2] , mo[N << 2];
	
	inline void maintain(int u){
		T[u] = max(T[lc] , T[rc]);
	}
	
	inline void pushdown(int u , int l , int r){
		if(mo[u] >= 0){
			tag[lc] = tag[rc] = 0;
			T[lc] = T[rc] = mo[lc] = mo[rc] = mo[u];
			mo[u] = -1;
		}
		if(tag[u]){
			tag[lc] += tag[u] ; tag[rc] += tag[u];
			T[lc] += tag[u] ; T[rc] += tag[u];
			tag[u] = 0;
		}
		return;
	}
	
	inline void Build(int u , int l , int r){
		mo[u] = -1;
		if(l == r){	
			T[u] = A[l];
			return;
		}
		Build(lc , l , mid) , Build(rc , mid + 1 , r);
		maintain(u);
	}
	
	inline void Modify_Point(int u , int l , int r , int p , int x){
		if(l == r){
			T[u] = x;
			mo[u] = x;
			tag[u] = 0;
			return;
		}
		pushdown(u , l , r);
		if(p <= mid) Modify_Point(lc , l , mid , p , x);
		else Modify_Point(rc , mid + 1 , r , p , x);
		maintain(u);
	}

	inline void Modify_Edge(int u , int l , int r , int L , int R , int x){
		if(L > r || R < l) return;
		if(l >= L && r <= R){
			T[u] = mo[u] = x;
			tag[u] = 0;
			return;
		}
		pushdown(u , l , r);
		if(L <= mid) Modify_Edge(lc , l , mid , L , R , x);
		if(R > mid) Modify_Edge(rc , mid + 1 , r , L , R , x);
		maintain(u);
	}
	
	inline void Add(int u , int l , int r , int L  , int R , int x){
		if(L > r || R < l) return;
		if(l >= L && r <= R){
			T[u] += x;
			tag[u] += x;
			return;
		}
		pushdown(u , l , r);
		if(L <= mid) Add(lc , l , mid , L , R , x);
		if(R > mid) Add(rc , mid + 1 , r , L , R , x);
		maintain(u);
	}
	
	inline int Ask(int u , int l , int r , int L , int R){
		if(l >= L && r <= R){
			return T[u];
		}	
		pushdown(u , l , r);
		if(R <= mid) return Ask(lc , l , mid , L , R);
		if(L > mid) return Ask(rc , mid + 1 , r , L , r);
		return max(Ask(lc , l , mid , L , R) , Ask(rc , mid + 1 , r , L , R));
	}
#undef lc
#undef rc
#undef mid
}

inline void Change(int u , int v , int x){
	while(top[u] != top[v]){
		if(dep[top[u]] < dep[top[v]]) swap(u , v);
		SegmentTree::Modify_Edge(1 , 1 , n , dfn[top[u]] , dfn[u] , x);
		u = fa[top[u]];
	}
	if(dfn[u] > dfn[v]) swap(u , v);
	if(dfn[u] != dfn[v]) SegmentTree::Modify_Edge(1 , 1 , n , dfn[u] + 1 , dfn[v] , x);
}

inline void ADD(int u , int v , int x){
	while(top[u] != top[v]){
		if(dep[top[u]] < dep[top[v]]) swap(u , v);
		SegmentTree::Add(1 , 1 , n , dfn[top[u]] , dfn[u] , x);
		u = fa[top[u]];
	}
	if(dfn[u] > dfn[v]) swap(u , v);
	if(dfn[u] != dfn[v]) SegmentTree::Add(1 , 1 , n , dfn[u] + 1 , dfn[v] , x);
}

inline int Ask_Q(int u , int v){
	int ans = 0;
	while(top[u] != top[v]){
		if(dep[top[u]] < dep[top[v]]) swap(u , v);
		ans = max(ans , SegmentTree::Ask(1 , 1 , n , dfn[top[u]] , dfn[u]));
		u = fa[top[u]];
	}
	if(dfn[u] > dfn[v]) swap(u , v);
	if(dfn[u] != dfn[v]) ans = max(ans , SegmentTree::Ask(1 , 1 , n , dfn[u] + 1 , dfn[v]));
	return ans;
}

signed main(){
	ios::sync_with_stdio(false) , cin.tie(0);
	cin >> n;
	for (int i = 1 ; i < n ; i++){
		int a , b , t;
		cin >> a >> b >> t;
		add(a , b , t);
		add(b , a , t);
	}
	
	dfs(1 , 0); hld(1 , 1);
	SegmentTree::Build(1 , 1 , n);
	string s;
	
	while(1){
		cin >> s;
		int u , v , k , w;
		if(s[0] == 'S') break;
		if(s[1] == 'h'){
			cin >> k >> w;
			k = k * 2 - 1;
			if(dep[e[k].to] < dep[e[k + 1].to]){
				k = e[k + 1].to;
			}
			else{
				k = e[k].to;
			}
			SegmentTree::Modify_Point(1 , 1 , n , dfn[k] , w);
		}
		if(s[1] == 'o'){
			cin >> u >> v >> w;
			Change(u , v , w);
		}
		if(s[1] == 'd'){
			cin >> u >> v >> w;
			ADD(u , v , w);
		}
		if(s[1] == 'a'){
			cin >> u >> v;
			cout << Ask_Q(u , v) << "\n";
		}
	}
	return 0;
}
2024/9/18 15:55
加载中...