有没有什么比较强的能手玩的数据分享一下吧
  • 板块CF888G Xor-MST
  • 楼主episode_
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/10/4 19:35
  • 上次更新2024/10/4 21:33:06
查看原帖
有没有什么比较强的能手玩的数据分享一下吧
1210996
episode_楼主2024/10/4 19:35

自己在cf上提交一直wa3,但是这个测试数据较长,后面都是省略号看不到,并且也不方便手玩

后来自己也试了一些能手玩的小数据,自己的输出都和通过代码一样

以下是自己的实现,写的是trie树更新查询的方法

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10, L = 30, NL2 = N * (L + 1) * 2;
struct trie
{
	int ch[2];
	int sz, id;
	trie(int _sz = 0)
	{
		ch[0] = ch[1] = -1;
		sz = _sz;
		id = 0;
	}
}tree[NL2];
struct connect
{
	int u, v, dist;
	connect(){};
	connect(int _u, int _v, int _dist)
	{
		u = _u;
		v = _v;
		dist = _dist;
	}
}con[N];
bool cmp(const connect &aa, const connect &bb)
{
	return aa.dist < bb.dist ||
	(aa.dist == bb.dist && aa.u < bb.u) ||
	(aa.dist == bb.dist && aa.u == bb.u && aa.v < bb.v);	
}
int a[N], fa[N], mindist[N];
int n, len = -1;
long long ans = 0;
int findf(int x)
{
	if(fa[x] == x)
		return x;
	fa[x] = findf(fa[x]);
	return fa[x];
}
void build(int root, int x)
{
	int id = root;
	for(int i = L - 1; i >= 0; --i)
	{
		int cur = (x >> i) & 1;
		tree[id].ch[cur] = ++len;
		tree[len] = trie(1);
		id = len;
	}
	tree[id].id = root;
}
void update(int des, int sou, int delta)
{
	tree[des].sz += tree[sou].sz * delta;
	if(tree[sou].id)
	{
		tree[des].id = tree[sou].id;
		return;
	}
	for(int i = 0; i <= 1; ++i)
	{
		if(tree[sou].ch[i] != -1)
		{
			if(tree[des].ch[i] == -1)
			{
				tree[des].ch[i] = ++len;
				tree[len] = trie();
			}
			update(tree[des].ch[i], tree[sou].ch[i], delta);
		}
	}
}
void findmin(int root, int x, int sou_id)
{
	int id = root, xorans = 0;
	for(int i = L - 1; i >= 0; --i)
	{
		int cur = (x >> i) & 1;
		if(tree[id].ch[cur] != -1 && tree[tree[id].ch[cur]].sz >= 1)
			id = tree[id].ch[cur];
		else
		{
			id = tree[id].ch[cur ^ 1];
			xorans |= (1 << i);
		}
	}
	con[sou_id] = connect(tree[id].id, sou_id, xorans);
}
int main()
{
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i)
		scanf("%d", &a[i]);
	sort(a + 1, a + 1 + n);
	n = unique(a + 1, a + 1 + n) - (a + 1);
	tree[++len] = trie();
	for(int i = 1; i <= n; ++i)
	{
		tree[++len] = trie(1);
		fa[i] = i;
	}
	for(int i = 1; i <= n; ++i)
		build(i, a[i]);
	for(int i = 1; i <= n; ++i)
		update(0, i, 1);
	int blocks = n;
	while(blocks > 1)
	{
		for(int i = 1; i <= n; ++i)
		{
			update(0, findf(i), -1);
			findmin(0, a[i], i);
			update(0, findf(i), 1);
		}
		sort(con + 1, con + 1 + n, cmp);
		for(int i = 1; i <= n; ++i)
		{
			int u = con[i].u, v = con[i].v;
			int x = findf(u), y = findf(v);
			if(x != y)
			{
				ans += con[i].dist;
				--blocks;
				if(tree[x].sz >= tree[y].sz)
				{
					fa[y] = x;
					update(x, y, 1);
				}
				else
				{
					fa[x] = y;
					update(y, x, 1); 
				}
				if(blocks == 1)
					break;
			}
		}
	}
	printf("%lld\n", ans);
}
2024/10/4 19:35
加载中...