社区讨论

线段树+树剖求调

P4315月下“毛景树”参与者 3已保存回复 7

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
7 条
当前快照
1 份
快照标识符
@m3yhlri9
此快照首次捕获于
2024/11/26 21:22
去年
此快照最后确认于
2025/11/04 13:51
4 个月前
查看原帖
RT,调了1个周了,救救孩子吧(
CPP
#define ios ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define int long long
#define ls p<<1
#define rs p<<1|1
using namespace std;
const int N = 1e5 + 5, inf = 2e18;
struct edge
{
	int to, pre, val;
} e[N << 1];
int cnt, last[N];
void addedge(int u, int v, int w)
{
	e[++cnt].pre = last[u], e[cnt].to = v;
	e[cnt].val = w,last[u] = cnt;
}
int f[N], dep[N], siz[N], son[N], dfn[N], top[N], rnk[N], tot;
int a[N], st[N];
void dfs1(int u, int fa)
{
	f[u] = fa, dep[u] = dep[fa] + 1;
	siz[u] = 1;
	for (int i = last[u]; i; i = e[i].pre)
	{
		int v = e[i].to;
		if (v == fa)
		{
			continue;
		}
		a[v] = e[i].val;
		dfs1(v, u);
		siz[u] += siz[v];
		if (siz[son[u]] < siz[v])
		{
			son[u] = v;
		}
	}
}
void dfs2(int u, int t)
{
	dfn[u] = ++tot;
	top[u] = t;
	rnk[cnt] = u;
	if (son[u])
	{
		dfs2(son[u], t);
	}
	for (int i = last[u]; i; i = e[i].pre)
	{
		int v = e[i].to;
		if (v == f[u] || v == son[u])
		{
			continue;
		}
		dfs2(v, v);
	}
}
struct Node
{
	int l, r, maxx, tag, tag2;//tag为加法标记,tag2为覆盖标记 
} t[N << 2];
void push_up(int p)
{
	t[p].maxx = max(t[ls].maxx, t[rs].maxx);
}
void build(int p, int l, int r)
{
	t[p].l = l, t[p].r = r;
	t[p].tag2 = -inf;
	if (l == r)
	{
		t[p].maxx = a[rnk[l]];
		return;
	}
	int mid = (l + r) >> 1;
	build(ls, l, mid);
	build(rs, mid + 1, r);
	push_up(p);
}
void push_down(int p)
{
	if (t[p].tag2 != -inf)
	{
		t[rs].tag2 = t[p].tag2, t[rs].tag2 = t[p].tag2;
		t[ls].tag=t[rs].tag=0;
		t[ls].maxx = t[rs].maxx = t[p].tag2;
		t[p].tag2 = -inf;
	}
	if (t[p].tag)
	{
		t[ls].tag += t[p].tag, t[rs].tag += t[p].tag;
		t[ls].maxx += t[p].tag, t[rs].maxx += t[p].tag;
		t[p].tag = 0;
	}
}
void add(int p, int l, int r, int k)
{
	if (l <= t[p].l && r >= t[p].r)
	{
		t[p].maxx += k;
		t[p].tag += k;
		return;
	}
	int mid = (t[p].l + t[p].r) >> 1;
	push_down(p);
	if (l <= mid)
	{
		add(ls, l, r, k);
	}
	if (r > mid)
	{
		add(rs, l, r, k);
	}
	push_up(p);
}
void modify(int p, int l, int r, int k)
{
	if (l <= t[p].l && r >= t[p].r)
	{
		t[p].tag = 0;
		t[p].tag2 = t[p].maxx = k;
		return;
	}
	push_down(p);
	int mid = (t[p].l + t[p].r) >> 1;
	if (l <= mid)
	{
		modify(ls, l, r, k);
	}
	if (r > mid)
	{
		modify(rs, l, r, k);
	}
	push_up(p);
}
int askmax(int p, int l, int r)
{
	if (l <= t[p].l && r >= t[p].r)
	{
		return t[p].maxx;
	}
	push_down(p);
	int mid = (t[p].l + t[p].r) >> 1;
	int maxx = -inf;
	if (l <= mid)
	{
		maxx = max(maxx, askmax(ls, l, r));
	}
	if (r > mid)
	{
		maxx = max(maxx, askmax(rs, l, r));
	}
	return maxx;
}
int max_path(int x, int y)
{
	int maxx = -inf;
	while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]])
		{
			swap(x, y);
		}
		maxx = max(maxx, askmax(1, dfn[top[x]], dfn[x]));
		x = f[top[x]];
	}
	if (dep[x] < dep[y])
	{
		swap(x, y);
	}
	maxx = max(maxx, askmax(1, dfn[y]+1, dfn[x]));
	return maxx;
}
void modify_path(int x, int y, int k)
{
	while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]])
		{
			swap(x, y);
		}
		modify(1, dfn[top[x]], dfn[x], k);
		x = f[top[x]];
	}
	if (dep[x] < dep[y])
	{
		swap(x, y);
	}
	modify(1, dfn[y]+1, dfn[x], k);
}
void add_path(int x, int y, int k)
{
	while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]])
		{
			swap(x, y);
		}
		add(1, dfn[top[x]], dfn[x], k);
		x = f[top[x]];
	}
	if (dep[x] < dep[y])
	{
		swap(x, y);
	}
	add(1, dfn[y] +1, dfn[x], k);
}
int u[N], v[N], w[N];
signed main()
{
//	freopen("1.in","r",stdin);
//	freopen("1.ans","w",stdout);
	ios;
	int n;
	cin >> n;
	for (int i = 1; i < n; i++)
	{
		cin >> u[i] >> v[i] >> w[i];
		addedge(u[i], v[i], w[i]);
		addedge(v[i], u[i], w[i]);
	}
	dfs1(1, 0);
	dfs2(1, 1);
	build(1, 1, n);
	for(int i=1; i<n; i++)
	{
		if(f[u[i]]==v[i])
		{
			st[i]=u[i];
		}
		else
		{
			st[i]=v[i];
		}
	}
	while (1)
	{
		string opt;
		cin >> opt;
		if (opt == "Stop")
		{
			break;
		}
		int l, r;
		cin >> l >> r;
		if (opt == "Change")
		{
			modify(1, dfn[st[l]],dfn[st[l]], r);
		}
		if (opt == "Cover")
		{
			int k;
			cin >> k;
			modify_path(l, r, k);
		}
		if (opt == "Add")
		{
			int k;
			cin >> k;
			add_path(l, r, k);
		}
		if (opt == "Max")
		{
			cout << max_path(l, r) << '\n';
		}
	}
	return 0;
}

回复

7 条回复,欢迎继续交流。

正在加载回复...