唐完了的萌新求助简单树剖模板 0pts 过样例。
查看原帖
唐完了的萌新求助简单树剖模板 0pts 过样例。
852144
Loser_Syx楼主2024/9/12 22:27
#include <iostream>
#include <cassert>
#include <queue>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <random>
#include <ctime>
#include <queue>
#include <map>
#include <set>
using namespace std;
#define int long long
#define pii pair<int, int>
#define eb emplace_back
#define F first
#define S second
#define test(x) cout << "Test: " << (x) << '\n'
#define lowbit(x) (x & -x)
#define debug puts("qwq");
#define open(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);
#define close fclose(stdin);fclose(stdout);
namespace FastIO {
	template <typename T = int>
	inline T read() {
		T s = 0, w = 1;
		char c = getchar();
		while (!isdigit(c)) {
			if (c == '-') w = -1;
			c = getchar();
		}
		while (isdigit(c)) s = (s << 1) + (s << 3) + (c ^ 48), c = getchar();
		return s * w;
	}
	template <typename T>
	inline void read(T &s) {
		s = 0;
		int w = 1;
		char c = getchar();
		while (!isdigit(c)) {
			if (c == '-') w = -1;
			c = getchar();
		}
		while (isdigit(c)) s = (s << 1) + (s << 3) + (c ^ 48), c = getchar();
		s = s * w;
	}
	template <typename T, typename... Arp> inline void read(T &x, Arp &...arp) {
		read(x), read(arp...);
	}
	template <typename T>
	inline void write(T x, char ch = '\n') {
		if (x < 0) x = -x, putchar('-');
		static char stk[25];
		int top = 0;
		do {
			stk[top++] = x % 10 + '0', x /= 10;
		} while (x);
		while (top) putchar(stk[--top]);
		putchar(ch);
		return;
	}
	template <typename T>
	inline void smax(T &x, T y) {
		if (x < y) x = y;
	}
	template <typename T>
	inline void smin(T &x, T y) {
		if (x > y) x = y;
	}
	void quit() {
		exit(0);
	}
} using namespace FastIO;
const int N = 1e5 + 19;
vector<int> g[N];
int dep[N], fa[N], son[N], siz[N], cnt, dfn[N], top[N], rnk[N], n, m, q, no[N], len;
pair<int, int> a[N], b[N];
pair<int, pii> Q[N];
struct DSU {
	int f[N];
	void init(int n) { for (int i = 1; i <= n; ++i) f[i] = i; }
	int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }
	void merge(int x, int y) { f[find(x)] = find(y); }
} dsu;
void dfs1(int u, int f) {
	fa[u] = f; dep[u] = dep[f] + 1; siz[u] = 1;
	for (auto i : g[u]) {
		if (i == f) continue;
		dfs1(i, u);
		if (siz[i] > siz[son[u]]) son[u] = i;
		siz[u] += siz[i];
	}
}
void dfs2(int u, int f) {
	top[u] = f; dfn[u] = ++cnt; rnk[cnt] = u;
	if (son[u]) dfs2(son[u], f);
	for (auto i : g[u]) if (i != fa[u] && i != son[u]) dfs2(i, i);
}
struct SegTree {
	int cnt[N << 2];
	#define ls (k << 1)
	#define rs (k << 1 | 1)
	#define mid ((l + r) >> 1)
	void build(int k, int l, int r) {
		cnt[k] = r - l + 1;
		if (l == r) return ;
		build(ls, l, mid); build(rs, mid+1, r);
	}
	void modify(int k, int l, int r, int L, int R) {
		if (L <= l && r <= R) return cnt[k] = 0, void();
		if (L <= mid) modify(ls, l, mid, L, R);
		if (R > mid) modify(rs, mid+1, r, L, R);
		cnt[k] = cnt[ls] + cnt[rs];
	}
	int query(int k, int l, int r, int L, int R) {
		if (L <= l && r <= R) return cnt[k];
		int ans = 0;
		if (L <= mid) ans += query(ls, l, mid, L, R);
		if (R > mid) ans += query(rs, mid+1, r, L, R);
		return ans;
	}
} seg;
void solve(int u, int v) {
	while (top[u] != top[v]) {
		if (dep[top[u]] > dep[top[v]]) swap(u, v);
		seg.modify(1, 1, n, dfn[top[v]], dfn[v]);
		v = fa[top[v]];
	}
	if (dep[u] > dep[v]) swap(u, v);
	if (u ^ v) seg.modify(1, 1, n, dfn[u]+1, dfn[v]);
} int query(int u, int v) {
	int ans = 0;
	while (top[u] != top[v]) {
		if (dep[top[u]] > dep[top[v]]) swap(u, v);
		ans += seg.query(1, 1, n, dfn[top[v]], dfn[v]);
		v = fa[top[v]];
	}
	if (dep[u] > dep[v]) swap(u, v);
	if (u ^ v) ans += seg.query(1, 1, n, dfn[u]+1, dfn[v]);
	return ans;
}
signed main() {
	read(n, m); dsu.init(n);
	for (int i = 1; i <= m; ++i) {
		read(a[i].F, a[i].S);
	}
	sort(a + 1, a + 1 + m);
	for (int op, u, v; (op = read()) != -1; ) {
		read(u, v); Q[++q] = {op, {u, v}};
		auto x = lower_bound(a + 1, a + 1 + m, make_pair(u, v));
		if (!op && *x == make_pair(u, v)) no[x - a] = 1;
	}
	for (int i = 1; i <= m; ++i) {
		if (!no[i]) {
			if (dsu.find(a[i].F) == dsu.find(a[i].S)) b[++len] = a[i];
			else g[a[i].F].eb(a[i].S), g[a[i].S].eb(a[i].F), dsu.merge(a[i].F, a[i].S);
		}
	} dfs1(1, 0); dfs2(1, 1); seg.build(1, 1, n); seg.modify(1, 1, n, 1, 1);
	for (int i = 1; i <= len; ++i) {
		solve(b[i].F, b[i].S);
	} vector<int> ans;
	for (int i = q; i; --i) {
		if (Q[i].F == 1) ans.eb(query(Q[i].S.F, Q[i].S.S));
		else solve(Q[i].S.F, Q[i].S.S);
	} reverse(ans.begin(), ans.end());
	for (int i : ans) write(i);
	return 0;
}
2024/9/12 22:27
加载中...