暴力树剖是过不了吗?
查看原帖
暴力树剖是过不了吗?
416242
New_hope楼主2024/3/9 22:40

我的代码 48pts ,全 T。

#include<bits/stdc++.h>
#define L (fa << 1)
#define R (fa << 1 | 1)
#define mid (l + r >> 1)
#define _ (int)(1e6 + 4)
using namespace std;

int n, k, o, ans;
vector<int> t[_];

int siz[_], d[_], fa[_], son[_], top[_], dfn[_];
void dfs1(int u, int p)
{
	for (int v : t[u]) {
		if (v == p) continue;
		fa[v] = u, d[v] = d[u] + 1;
		dfs1(v, u);
		siz[u] += siz[v];
		son[u] = (siz[v] > siz[son[u]] ? v : son[u]);
	}
}
void dfs2(int u, int tp)
{
	dfn[u] = ++o, top[u] = tp;
	if (son[u]) dfs2(son[u], tp);
	for (int v : t[u]) {
		if (v == fa[u] || v == son[u]) continue;
		dfs2(v, v);
	}
}
int sum[_ << 2], tg[_ << 2];
void pd(int fa) 
{
	if (!tg[fa]) return ;
	sum[L] += tg[fa], tg[L] += tg[fa]; 
	sum[R] += tg[fa], tg[R] += tg[fa];
	tg[fa] = 0;
	return;
}
int get(int fa, int l, int r, int p)
{
	if (l == r) return sum[fa];
	pd(fa);
	if (p <= mid)  return get(L, l, mid, p);
	if (p > mid) return get(R, mid+1, r, p);
}
void update(int fa, int l, int r, int ql, int qr)
{
	if(ql > qr) return;
	if (ql <= l && r <= qr) {
		tg[fa] ++, sum[fa] ++;
		return;
	}
	pd(fa);
	if (ql <= mid)  update(L, l, mid, ql, qr);
	if (qr > mid) update(R, mid+1, r, ql, qr);
}
void tup(int u, int v)
{
	while (top[u] != top[v]) {
		if (d[top[u]] < d[top[v]]) swap(u, v);
		update(1, 1, n, dfn[top[u]], dfn[u]);
		u = fa[top[u]];
	}
	if (d[u] < d[v]) swap(u, v);
	update(1, 1, n, dfn[v], dfn[u]);
}
int main()
{
	scanf("%d %d", &n, &k);
	for (int i = 1; i < n; i ++) {
		int x, y; scanf("%d %d", &x, &y);
		t[x].push_back(y);
		t[y].push_back(x);	
	}
	dfs1(1, 0), dfs2(1, 0);
	for (int i = 1; i <= k; i ++) {
		int s, t; scanf("%d %d", &s, &t);
		tup(s, t);
	}
	for (int i = 1; i <= n; i ++) {
		ans = max(ans, get(1, 1, n, dfn[i]));
	}
	printf("%d", ans);
	
	return 0;
}
2024/3/9 22:40
加载中...