社区讨论

蒟蒻求助,80,MLE

P3258[JLOI2014] 松鼠的新家参与者 1已保存回复 1

讨论操作

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

当前回复
1 条
当前快照
1 份
快照标识符
@mi860lia
此快照首次捕获于
2025/11/21 09:12
4 个月前
此快照最后确认于
2025/11/21 09:12
4 个月前
查看原帖
为什么会MLE啊!!!
树剖板子拿过来用
CPP
#include<bits/stdc++.h>
using namespace std;
struct Edge
{
	int fr, to;
}eg[400005];
int head[100005], edgenum;
struct SegNode
{
	int l, r, val, lazy;
}sn[800005];
struct TreeNode
{
	int fa, deep, son, id, top, size, val;
}tn[400005];
int road[100005], n, r, ans[100005];
inline void add(int fr, int to)
{
	eg[++edgenum].fr = head[fr];
	eg[edgenum].to = to;
	head[fr] = edgenum;
}
inline void pushup(int rt)
{
	sn[rt].val = sn[rt << 1].val + sn[rt << 1 | 1].val;
}
inline void pushdown(int rt, int len)
{
	if (sn[rt].lazy)
	{
		sn[rt << 1].lazy += sn[rt].lazy;
		sn[rt << 1 | 1].lazy += sn[rt].lazy;
		sn[rt << 1].val += sn[rt].lazy * (len - (len >> 1));
		sn[rt << 1 | 1].val += sn[rt].lazy * (len >> 1);
		sn[rt].lazy = 0;
	}
}
inline int query(int rt, int l, int r, int fr, int to)
{
	int ans = 0;
	if (fr <= l && to >= r)
	{
		return sn[rt].val;
	}
	pushdown(rt, r - l + 1);
	int mid = (l + r) >> 1;
	if (fr <= mid) ans += query(rt << 1, l, mid, fr, to);
	if (to > mid) ans += query(rt << 1 | 1, mid + 1, r, fr, to);
	return ans;
}
inline void update(int rt, int l, int r, int fr, int to, int val)
{
	if (fr <= l && to >= r)
	{
		sn[rt].lazy += val;
		sn[rt].val += val * (r - l + 1);
		return;
	}
	pushdown(rt, r - l + 1);
	int mid = (l + r) >> 1;
	if (fr <= mid) update(rt << 1, l, mid, fr, to, val);
	if (to > mid) update(rt << 1 | 1, mid + 1, r, fr, to, val);
	pushup(rt);
}
inline void build(int rt, int l, int r)
{
	if (l > r) return;
	sn[rt].l = l;
	sn[rt].r = r;
	sn[rt].lazy = 0;
	if (l == r)
	{
		sn[rt].val = tn[l].val;
		return;
	}
	int mid = (l + r) >> 1;
	build(rt << 1, l, mid);
	build(rt << 1 | 1, mid + 1, r);
	pushup(rt);
}
int cnt;
inline void dfs1(int x, int fa, int deep)
{
	tn[x].deep = deep;
	tn[x].fa = fa;
	tn[x].size = 1;
	int maxson = -1;
	for (int i = head[x]; i; i = eg[i].fr)
	{
		if (eg[i].to == fa) continue;
		dfs1(eg[i].to, x, deep + 1);
		tn[x].size += tn[eg[i].to].size;
		if (tn[eg[i].to].size > maxson)
			maxson = tn[eg[i].to].size, tn[x].son = eg[i].to;
	}
}
inline void dfs2(int x, int top)
{
	tn[x].id = ++cnt;
	tn[x].top = top;
	tn[cnt].val = 0;
	if (!tn[x].son) return;
	dfs2(tn[x].son, top);
	for (int i = head[x]; i; i = eg[i].fr)
	{
		if (eg[i].to == tn[x].fa || eg[i].to == tn[x].son)
			continue;
		dfs2(eg[i].to, eg[i].to);
	}
}
inline void updateroad(int x, int y, int val)
{
	while (tn[x].top != tn[y].top)
	{
		if (tn[tn[x].top].deep < tn[tn[y].top].deep) swap(x, y);
		update(1, 1, n, tn[tn[x].top].id, tn[x].id, val);
		x = tn[tn[x].top].fa;
	}
	if (tn[x].deep > tn[y].deep) swap(x, y);
	update(1, 1, n, tn[x].id, tn[y].id, val);
}
inline int queryroad(int x, int y)
{
	int ans = 0;
	while (tn[x].top != tn[y].top)
	{
		if (tn[tn[x].top].deep < tn[tn[y].top].deep) swap(x, y);
		ans += query(1, 1, n, tn[tn[x].top].id, tn[x].id);
		x = tn[tn[x].top].fa;
	}
	if (tn[x].deep > tn[y].deep) swap(x, y);
	ans += query(1, 1, n, tn[x].id, tn[y].id);
	return ans;
}
int main()
{
	freopen("testdata.in", "r", stdin);
	freopen("testout.out", "w", stdout);
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i)
		scanf("%d", &road[i]);
	int a, b;
	for (int i = 1; i < n; ++i)
	{
		scanf("%d%d", &a, &b);
		add(a, b);
		add(b, a);
	}
	r = 1;
	dfs1(r, 0, 1);
	dfs2(r, r);
	build(1, 1, n);
	for (int i = 1; i < n; ++i)
		updateroad(road[i], road[i + 1], 1);
	for (int i = 1; i <= n; ++i)
		ans[i] = query(1, 1, n, tn[i].id, tn[i].id);
	for (int i = 2; i <= n; ++i)
		--ans[road[i]];
	for (int i = 1; i <= n; ++i)
		printf("%d\n", ans[i]);
	return 0;
}

回复

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

正在加载回复...