萌新刚学树剖wa0求调
查看原帖
萌新刚学树剖wa0求调
748131
IcyL楼主2023/10/10 20:10

rt

#include<bits/stdc++.h>
#define PII pair<int, int>
#define fst first
#define scd second
#define int long long
#define l(u) u << 1
#define r(u) u << 1 | 1
#define FH signed

using namespace std;

const int N = 1e5 + 10;

PII edge[N];
int d[N], f[N], siz[N], son[N], top[N], a[N], id[N], wc[N], cnt;
vector<PII> e[N];

struct node
{
	int l, r;
	int maxx;
	int add, cov;
} tr[N * 4];


void dfs1(int u, int fa, int dep)
{
	d[u]  = dep;
	f[u] = fa;
	siz[u] = 1;
	int maxx = 0;
	for(auto v : e[u])
	{
		if(v.fst == fa) continue;
		dfs1(v.fst, u, dep + 1);
		a[v.fst] = v.scd;
		siz[u] += siz[v.fst];
		if(maxx < siz[v.fst])
			maxx = siz[v.fst], son[u] = v.fst;
	}
}

void dfs2(int u, int t)
{
	id[u] = ++ cnt;
	wc[cnt] = a[u];
	top[u] = t;
	if(!son[u]) return ;
	dfs2(son[u], t);
	for(auto v : e[u])
	{
		if(v.fst == son[u] || v.fst == f[u]) continue;
		dfs2(v.fst, v.fst);
	}
}

void pushup(int u)
{
	tr[u].maxx = max(tr[l(u)].maxx, tr[r(u)].maxx);
}

void pushdown(int u)
{
	if(tr[u].cov != -1)
		tr[l(u)].maxx = tr[r(u)].maxx = tr[u].cov,
		tr[l(u)].cov = tr[r(u)].cov = tr[u].cov;
	tr[l(u)].maxx += tr[u].add;
	tr[r(u)].maxx += tr[u].add;
	tr[l(u)].add += tr[u].add;
	tr[r(u)].add += tr[u].add;
	tr[u].cov = -1, tr[u].add = 0;
}

void build(int u, int l ,int r)
{
	tr[u] = {l, r, 0, 0, -1};
	if(l == r)
	{
		tr[u].maxx = wc[l];
		return ;
	}
	
	int mid = l + r >> 1;
	build(l(u), l, mid);
	build(r(u), mid + 1, r);
	pushup(u);
}

void modify(int u, int l, int r, int cov, int add)
{
	if(l <= tr[u].l && tr[u].r <= r) 
	{
		if(cov != -1)
			tr[u].maxx = tr[u].cov = cov,
			tr[u].add = 0;
		tr[u].maxx += add;
		tr[u].add += add;
		return ;
	}
	
	pushdown(u);
	int mid = tr[u].l + tr[u].r >> 1;
	if(l <= mid) modify(l(u), l, r, cov, add);
	if(r > mid) modify(r(u), l, r, cov, add);
	pushup(u);
}

void modify(int u, int x, int cov, int add)
{
	if(tr[u].l == tr[u].r) 
	{
		if(cov != -1)
			tr[u].maxx = tr[u].cov = cov,
			tr[u].add = 0;
		tr[u].maxx += add;
		tr[u].add += add;
		return ;
	}
	
	pushdown(u);
	int mid = tr[u].l + tr[u].r >> 1;
	if(x <= mid) modify(l(u), x, cov, add);
	else modify(r(u), x, cov, add);
	pushup(u);
}

int query(int u, int l, int r)
{
	if(l <= tr[u].l && tr[u].r <= r) 
		return tr[u].maxx;
	
	pushdown(u);
	int mid = tr[u].l + tr[u].r >> 1, res = 0;
	if(l <= mid) res = max(res, query(l(u), l, r));
	if(r > mid) res = max(res, query(r(u), l, r));
	return res;	
}

void modify_range(int x, int y, int cov, int add)
{
	while(top[x] != top[y])
	{
		if(d[top[x]] < d[top[y]]) swap(x, y);
		modify(1, id[top[x]], id[x], cov, add);
		x = f[top[x]];
	}
	if(d[x] > d[y]) swap(x, y);
	modify(1, id[x] + 1, id[y], cov, add);
}

int query_range(int x, int y)
{
	int res = 0;
	while(top[x] != top[y])
	{
		if(d[top[x]] < d[top[y]]) swap(x, y);
		res = max(res, query(1, id[top[x]], id[x]));
		x = f[top[x]];
	}
	if(d[x] > d[y]) swap(x, y);
	res = max(res, query(1, id[x] + 1, id[y]));
	return res;
}

FH 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;
    	e[a].push_back({b, c});
    	e[b].push_back({a, c});
    	edge[i] = {a, b};
	}
	
	dfs1(1, 0, 1);
	dfs2(1, 1);
	build(1, 1, n);
	
	while(1)
	{
		string opt;
		cin >> opt;
		if(opt[0] == 'S') break;
		int k, u, v, w;
		if(opt[1] == 'h')
		{
			cin >> k >> w;
			if (d[edge[k].fst] > d[edge[k].scd]) k = edge[k].fst;
			else k = edge[k].scd;
			modify(1, id[k], w, 0);
		}
		if(opt[1] == 'o')
		{
			cin >> u >> v >> w;
			modify_range(u, v, w, 0);
		}
		if(opt[1] == 'd')
		{
			cin >> u >> v >> w;
			modify_range(u, v, -1, w);
		}
		if(opt[1] == 'a')
		{
			cin >> u >> v;
			cout << query_range(u, v) << "\n";
		}
	}   
    return 0;
}
2023/10/10 20:10
加载中...