树剖求助,WA的都是在百行左右
查看原帖
树剖求助,WA的都是在百行左右
762588
Edgebright楼主2023/8/10 21:56
#include<bits/stdc++.h>
#define __lg(x) ((x) ? __lg(x) : 0)
typedef long long ll;
using namespace std;
const int N = 100005, Lg = 20;
int dfn[N], hvy[N], sz[N], a[N], inv[N], top[N];
int anc[Lg][N], dep[N];
int id[N], inv_id[N];
int stp;
int n;
struct edge
{
	int n, t, w, id; 
}e[N << 1];
int h[N], ce;
inline void add(int u, int v, int w, int id)
{
	e[++ce] = {h[u], v, w, id};
	h[u] = ce; return;
}
void getsz(int u, int f)
{
	sz[u] = 1;
	anc[0][u] = f; dep[u] = dep[f] + 1;
	for(int i = h[u]; i; i = e[i].n)
	{
		int to = e[i].t; if(to == f) continue;
		a[to] = e[i].w;
		id[to] = e[i].id;
		getsz(to, u);
		if(sz[to] > sz[hvy[u]])
		{
			hvy[u] = to;
		}
		sz[u] += sz[to];
	}
	return;
}
void decomp(int u, int f)
{
	dfn[u] = ++stp;
	top[u] = ((u == hvy[f]) ? top[f]: u);
	if(hvy[u]) decomp(hvy[u], u);
	for(int i = h[u]; i; i = e[i].n)
	{
		int to = e[i].t;
		if(to == f || to == hvy[u]) continue;
		decomp(to, u);
	}
	return;
}
void inverse()
{
	for(int i = 1; i <= n; ++i)
	{
		inv[dfn[i]] = i;
	}
	for(int i = 1; i <= n; ++i)
	{
		inv_id[id[i]] = i;
	}
}
struct nd
{
	int l, r;
	int mx, tag, add;
};
struct segt
{
	nd s[N << 2];
	inline void upd(int p)
	{
		s[p].mx = max(s[p<<1].mx, s[p<<1|1].mx);
	}
	inline void spread(int p)
	{
		if(s[p].tag != -1)
		{
			s[p<<1].tag = s[p<<1].mx = s[p].tag;
			s[p<<1].add = 0;
			s[p<<1|1].tag = s[p<<1|1].mx = s[p].tag;
			s[p<<1|1].add = 0;
			s[p].tag = -1; s[p].add = 0;
			return;	
		}
		else if(s[p].add)
		{
			s[p<<1].add += s[p].add;
			s[p<<1].mx += s[p].add;
			s[p<<1|1].add += s[p].add;
			s[p<<1|1].mx += s[p].add;
			s[p].add = 0;
			return;
		}
	}
	void build(int p, int l, int r)
	{
		s[p].l = l; s[p].r = r;
		s[p].tag = -1; s[p].add = 0;
		if(l == r)
		{
			s[p].mx = a[inv[l]]; return;
		}
		int Md = (l + r) >> 1;
		build(p<<1, l, Md);
		build(p<<1|1, Md + 1, r);
		upd(p); return;
	}
	void change(int p, int x, int w)
	{
		if(s[p].l == s[p].r)
		{
			s[p].mx = w; return;
		}
		spread(p);
		int Md = (s[p].l + s[p].r) >> 1;
		if(x <= Md) change(p<<1, x, w);
		else change(p<<1|1, x, w);
		upd(p);
		return;
	}
	void cover(int p, int l, int r, int w)
	{
		if(l > r) return;
		if(l <= s[p].l && s[p].r <= r)
		{
			s[p].mx = s[p].tag = w; return;
		}
		spread(p);
		int Md = (s[p].l + s[p].r) >> 1;
		if(l <= Md) cover(p<<1, l, r, w);
		if(r > Md) cover(p<<1|1, l ,r, w);
		upd(p);
		return;
	}
	void Add(int p, int l ,int r, int d)
	{
		if(l > r) return;
		spread(p);
		if(l <= s[p].l && s[p].r <= r)
		{
			s[p].mx += d; s[p].add += d; return;
		}
		int Md = (s[p].l + s[p].r) >> 1;
		if(l <= Md) Add(p<<1, l, r, d);
		if(r > Md) Add(p<<1|1, l, r, d);
		upd(p);
		return;
	}
	int query(int p, int l, int r)
	{
		if(l > r) return 0;
//		printf("L%d R%d\n",l, r);
		if(l <= s[p].l && s[p].r <= r)
		{
			return s[p].mx;
		}
		spread(p);
		int mx = 0, Md = (s[p].l + s[p].r) >> 1;
		if(l <= Md) mx = max(mx, query(p<<1, l, r));
		if(r > Md) mx = max(mx, query(p<<1|1, l, r));
		return mx;
	}
};
segt t;
void get_anc()
{
	for(int ex = 1; ex <= __lg(n); ++ex)
	{
		for(int i = 1; i <= n; ++i)
		{
			anc[ex][i] = anc[ex - 1][anc[ex - 1][i]];
		}
	}
	return;
}
int get_lca(int u, int v)
{
	if(dep[u] < dep[v]) swap(u, v);
	while(dep[u] > dep[v])
	{
		u = anc[__lg(dep[u] - dep[v])][u];
	}
	if(u == v) return u;
	for(int ex = __lg(dep[u]); ex >= 0; --ex)
	{
		if(anc[ex][u] == anc[ex][v]) continue;
		u = anc[ex][u]; v = anc[ex][v];
	}
	return anc[0][u];
}
void chain_cover(int u, int v, int w)
{
	if(dep[u] < dep[v]) swap(u, v);
	while(dep[top[u]] > dep[v])
	{
		t.cover(1, dfn[top[u]], dfn[u], w);
		u = anc[0][top[u]];
	}
	t.cover(1, dfn[v] + 1, dfn[u], w);
	return;
}
void chain_add(int u, int v, int d)
{
	if(dep[u] < dep[v]) swap(u, v);
	while(dep[top[u]] > dep[v])
	{
		t.Add(1, dfn[top[u]], dfn[u], d);
		u = anc[0][top[u]];
	}
	t.Add(1, dfn[v] + 1, dfn[u], d);
	return;
}
int chain_qry(int u, int v)
{
	if(dep[u] < dep[v]) swap(u, v);
	int res = 0;
	while(dep[top[u]] > dep[v])
	{
		res = max(res, t.query(1, dfn[top[u]], dfn[u]));
		u = anc[0][top[u]];
	}
	res = max(res, t.query(1, dfn[v] + 1, dfn[u]));
	return res;
}
signed main()
{
//	freopen("tree.in", "r", stdin);
	scanf("%d", &n);
	for(int i = 1; i < n; ++i)
	{
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);
		add(u, v, w, i); add(v, u, w, i);
	}
	getsz(1, 0);
	decomp(1, 0);
	inverse();
	get_anc();
	t.build(1, 1, n);
	char op[7];//0_index
	while(scanf("%s", op), op[2] != 'o')
	{
		if(op[2] == 'a')//change
		{
			int k, w; scanf("%d%d", &k, &w);
			t.change(1, dfn[inv_id[k]], w);
		}
		else if(op[2] == 'v')//cover
		{
			int u, v, w;
			scanf("%d%d%d", &u, &v, &w);
			int lca = get_lca(u, v);
			chain_cover(lca, u, w);//(lca,u]
			chain_cover(lca, v, w);
		}
		else if(op[2] == 'd')
		{
			int u, v, w;
			scanf("%d%d%d", &u, &v, &w);
			int lca = get_lca(u, v);
			chain_add(lca, u, w);//(lca,u]
			chain_add(lca, v, w);
		}
		else if(op[2] == 'x')
		{
			int u, v, w;
			scanf("%d%d", &u, &v);
			int lca = get_lca(u, v);
//			printf("lca%d\n", lca);
			int mx = 0;
			mx = max(mx, chain_qry(lca, u));
			mx = max(mx, chain_qry(lca, v));
			printf("%d\n", mx);
		}
	}
	return 0;
}
2023/8/10 21:56
加载中...