kruskal 重构树 + st 表求hack
查看原帖
kruskal 重构树 + st 表求hack
947565
_ERO_楼主2023/10/16 19:15

rt,

#include<cstdio>
#include<algorithm>
using namespace std;

const int MAXN = 1000005;

int T;
int n, m, Q;
int val[MAXN << 1];
struct E {
	int u, v;
}a[MAXN];
struct edge {
	int to, nex;
}e[MAXN << 1]; int idx, head[MAXN];
inline void add(int u, int v) {
	e[++ idx].to = v;
	e[idx].nex = head[u];
	head[u] = idx;
}

namespace UNQ {
	int MX, fa[MAXN];
	inline void Init(int x) {
		MX = x;
		for (int i = 1; i <= MX; ++ i)
			fa[i] = i;
	}
	inline int Find(int x) {return x == fa[x] ? x : fa[x] = Find(fa[x]);}
	inline void Merge(int u, int v) {
		u = Find(u), v = Find(v);
		fa[u] = v;
	}
}
int fa[MAXN][25], dep[MAXN];
inline void dfs(int u) {
	for (int i = 1; i <= 18; ++ i)
		fa[u][i] = fa[fa[u][i - 1]][i - 1];
	for (int i = head[u]; i; i = e[i].nex) {
		int v = e[i].to;
		fa[v][0] = u;
		dep[v] = dep[u] + 1;
		dfs(v);
	}
}
inline void Build() {
	UNQ::Init(n << 1);
	int ct = n;
	for (int i = 1; i <= m; ++ i) {
		int u = UNQ::Find(a[i].u);
		int v = UNQ::Find(a[i].v);
		if (u == v) continue;
		++ ct;
		val[ct] = i;
		add(ct, u), add(ct, v);
		UNQ::Merge(u, ct), UNQ::Merge(v, ct);
	}
	dep[ct] = 0;
	dfs(ct);
}
inline int Lca(int u, int v) {
	if (dep[u] < dep[v]) swap(u, v);
	for (int i = 18; ~i; -- i)
		if (dep[fa[u][i]] >= dep[v])
			u = fa[u][i];
	if (u == v) return u;
	for (int i = 18; ~i; -- i)
		if (fa[u][i] != fa[v][i])
			u = fa[u][i], v = fa[v][i];
	return fa[u][0];
}

int f[MAXN][25], lg[MAXN];
inline void Init() {
	for (int i = 2; i <= n; ++ i)
		lg[i] = lg[i >> 1] + 1;
	for (int i = 2; i <= n; ++ i)
		f[i][0] = val[Lca(i, i - 1)];
	for (int j = 1; j <= 18; ++ j)
		for (int i = 1; i <= n; ++ i)
			f[i][j] = max(f[i][j - 1], f[i + (1 << j) - 1][j - 1]);
}
inline int Get(int l, int r) {
	int j = lg[r - l + 1];
	return max(f[l][j], f[r - (1 << j) + 1][j]);
}
inline void Clear() {
	for (int i = 1; i <= n; ++ i) head[i] = 0;
	for (int i = 1; i <= idx; ++ i)
		e[i].nex = 0;
	for (int j = 0; j <= 18; ++ j)
		for (int i = 1; i <= n; ++ i)
			f[i][j] = 0;
}

int main()
{
	scanf ("%d", &T);
	while (T --) {
		scanf ("%d%d%d", &n, &m, &Q);
		for (int i = 1; i <= m; ++ i)
			scanf ("%d%d", &a[i].u, &a[i].v);
		Build();
		Init();
		while (Q --) {
			int l, r; 
			scanf ("%d%d", &l, &r);
			if (l >= r) printf ("0 ");
			else printf ("%d ", Get(l + 1, r));
		}
		puts("");
		Clear();
	}
	return 0;
}

第二点就挂了,cf还上不去(悲

蒟蒻不会生成联通图

2023/10/16 19:15
加载中...