MnZn树剖做法WA50求助
查看原帖
MnZn树剖做法WA50求助
542070
zdl777楼主2023/2/19 17:08
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#define rep(i, l, r) for(int i = l; i <= r; ++ i)
#define repd(i, r, l) for(int i = r; i >= l; -- i)

using namespace std;

const int N = 100010;

int n, m;
int head[N], ver[N << 1], Next[N << 1], tot = 0;
int siz[N], son[N], fa[N], dep[N], top[N], dfn[N], tim = 0;
int c[N], f[N];

struct Query
{
	int op, x, y;
} q[N];

int get(int x)
{
	return (f[x] == x) ? x : f[x] = get(f[x]); 
}
void merge(int x, int y)
{
	f[get(y)] = get(x);
}
int lowbit(int x)
{
	return x & (-x);
}
void add(int x, int y)
{
	for(; x <= n; x += lowbit(x)) c[x] += y;
}
int ask(int x)
{
	int ans = 0;
	for(; x; x -= lowbit(x)) ans += c[x];
	return ans;
}
void dfs1(int x, int pa)
{
	siz[x] = 1;
	son[x] = -1;
	fa[x] = pa;
	dep[x] = dep[pa] + 1;
	for(int i = head[x]; i; i = Next[i])
	{
		int y = ver[i];
		if(y == pa) continue;
		dfs1(y, x);
		siz[x] += siz[y];
		if(son[x] == -1 || siz[y] > siz[son[x]]) son[x] = y;
	}
}
void dfs2(int x, int t)
{
	top[x] = t;
	dfn[x] = ++tim;
	if(son[x] != -1) dfs2(son[x], t);
	for(int i = head[x]; i; i = Next[i])
	{
		int y = ver[i];
		if(y == fa[x] || y == son[x]) continue;
		dfs2(y, y);
	}
}
void add_path(int x, int y, int val)
{
	while(top[x] != top[y])
	{
		if(dep[top[x]] < dep[top[y]]) swap(x, y);
		add(dfn[top[x]], val);
		add(dfn[x] + 1, -val);
		x = fa[top[x]];
	}
	if(dep[x] > dep[y]) swap(x, y);
	add(dfn[x], val);
	add(dfn[y] + 1, -val);
}
void add_edge(int x, int y)
{
	ver[++tot] = y;
	Next[tot] = head[x], head[x] = tot;
}

int main()
{
	scanf("%d%d", &n, &m);
	rep(i, 1, n) f[i] = i;
	rep(i, 1, m)
	{
		char op;
		cin >> op;
		scanf("%d%d", &q[i].x, &q[i].y);
		if(op == 'A')
		{
			int x = q[i].x, y = q[i].y;
			q[i].op = 0;
			add_edge(x, y);
			add_edge(y, x);
		}
		else q[i].op = 1;
	}
	rep(i, 1, m) if(q[i].op == 0) merge(q[i].x, q[i].y);
	rep(i, 1, n) if(i == get(i)) { add_edge(n + 1, i); add_edge(i, n + 1); }
	dfs1(n + 1, 0);
	dfs2(n + 1, n + 1);
	rep(i, 1, n) f[i] = i;
	add(1, 1);
	rep(i, 1, m)
	{
		int op = q[i].op, x = q[i].x, y = q[i].y;
		if(y == fa[x]) swap(x, y);
		if(op == 0) 
		{
			add_path(x, get(x), ask(dfn[y]));
			merge(x, y);
		}
		else 
		{
			long long ans = 0;
			int sizy = ask(dfn[y]), sizx = ask(dfn[get(x)]) - sizy;
			ans = 1ll * sizx * sizy;
			printf("%lld\n", ans);
		}
	}
	return 0;
}
2023/2/19 17:08
加载中...