蒟蒻刚学树剖,爆0求助
查看原帖
蒟蒻刚学树剖,爆0求助
498612
Saka_Noa楼主2022/8/16 07:33
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 1000005
#define lc k<<1
#define rc k<<1|1
#define lcon lc,l,mid
#define rcon rc,mid+1,r
#define Mid int mid = (l+r) >> 1
#define inf -0x7ffffffff

struct EDGE{
	int next,to,w;
}e[N<<1];
int head[N],cnt;
void edge_add(int f,int t,int v) {
	e[++cnt] = (EDGE) {head[f],t,v};
	head[f] = cnt;//First!!
}
int fa[N],de[N],to[N],si[N],so[N],se[N],re[N];
int value[N];
void dfs1(int f,int u) {
	fa[u] = f;
	de[u] = de[f] + 1;
	si[u] = 1;
	for(int i = head[u];i;i = e[i].next) {
		int v = e[i].to,va = e[i].w;
		if(v == f) continue;
		value[v] = va;
		dfs1(u,v);
		si[u] += si[v];
		if(si[v] > si[so[u]]) so[u] = v;
	}
}
void dfs2(int u,int tof) {
	to[u] = tof;
	se[u] = ++se[0];
	re[se[0]] = u;
	if(!so[u]) return;
	dfs2(so[u],tof);
	for(int i = head[u];i;i = e[i].next) {
		int v = e[i].to;
		if(v == fa[u] || v == so[u]) continue;
		dfs2(v,v);
	}
}
int tmax[N<<2];
int add[N<<2],fu[N<<2];
void pushup(int k) {
	tmax[k] = max(tmax[lc],tmax[rc]);
}
void build(int k,int l,int r) {
	fu[k] = inf;
	if(l == r) {
		tmax[k] = value[re[l]]; //Second!!
		return;
	}
	Mid;
	build(lcon);
	build(rcon);
	pushup(k);
}
void cha(int k,int v) {
	fu[k] = v;
	tmax[k] = v;
}
void Add(int k,int v) {
	if(fu[k] != inf) cha(k,v+fu[k]);
	add[k] += v;
	tmax[k] += v;
}
void pushdown(int k) {
	Add(lc,add[k]);
	Add(rc,add[k]);
	add[k] = 0;
	if(fu[k] != inf) {
		cha(lc,fu[k]);
		cha(rc,fu[k]);
		fu[k] = inf;
	}
}
void modify(int k,int l,int r,int x,int y,int v) {
	if(x <= l && r <= y) {
		Add(k,v);
		return;
	}
	pushdown(k);
	Mid;
	if(x <= mid) modify(lcon,x,y,v);
	if(y > mid) modify(rcon,x,y,v);
	pushup(k);
}
void modifc(int k,int l,int r,int x,int y,int v) {
	if(x <= l && r <= y) {
		cha(k,v);
		return;
	}
	pushdown(k);
	Mid;
	if(x <= mid) modifc(lcon,x,y,v);
	if(y > mid) modifc(rcon,x,y,v);
	pushup(k);
}
int query(int k,int l,int r,int x,int y) {
	if(x <= l && r <= y) return tmax[k];
	if(y < l || x > r) return inf;
	pushdown(k);
	Mid,ans = inf;
	if(x <= mid) ans = max(ans,query(lcon,x,y));
	if(y > mid ) ans = max(ans,query(rcon,x,y));
	return ans;
}

int n;
int ui,vi,wi;
void t_add(int x,int y,int w) {
	while(to[x] != to[y]) {
		if(de[to[x]] < de[to[y]]) swap(x,y);
		modify(1,1,se[0],se[to[x]],se[x],w);
		x = fa[to[x]];
	}
	if(de[x] > de[y]) swap(x,y);
	modify(1,1,se[0],se[x]+1,se[y],w);
}
void t_fu(int x,int y,int w) {
	while(to[x] != to[y]) {
		if(de[to[x]] < de[to[y]]) swap(x,y);
		modifc(1,1,se[0],se[to[x]],se[x],w);
		x = fa[to[x]];
	}
	if(de[x] > de[y]) swap(x,y);
	modifc(1,1,se[0],se[x]+1,se[y],w);
}
int ask_max(int x,int y) {
	int ans = inf;
	while(to[x] != to[y]) {
		if(de[to[x]] < de[to[y]]) swap(x,y);
		ans = max(ans,query(1,1,se[0],se[to[x]],se[x]));
		x = fa[to[x]];
	}
	if(de[x] > de[y]) swap(x,y);
	ans = max(ans,query(1,1,se[0],se[x]+1,se[y]));
	return ans;
}
string s;
int l, r, 
v;
int U[N],V[N];
signed main() {
    cin >> n;
    for(int i = 1;i < n;i++) {
		cin >> ui >> vi >> wi;
		U[i] = ui,V[i] = vi;
		edge_add(ui,vi,wi);
		edge_add(vi,ui,wi);
    }
    //cout << cnt;
    
    dfs1(0,1);
    dfs2(1,1);
	//cout << se[0];
    build(1,1,se[0]);
	
    cin >> s;
    while(s != "Stop") {
		cin >> l >> r;
		if(s == "Max") cout << ask_max(l,r) << endl;
		else if(s == "Change"){
			int fr = U[l],to = V[l];
			if(de[fr] < de[to]) swap(fr,to);
			modifc(1,1,se[0],se[fr],se[fr],r);
		}
		else {
			cin >> v;
			if(s == "Cover") t_fu(l,r,v);
			else if(s == "Add") t_add(l,r,v);
		}
		cin >> s;
    }
    
    
    
    return 0;
}
2022/8/16 07:33
加载中...