2139: road

把a[i], b[i]分开来排序

对应位置上的点连边

感性理解这是最小的

会连出若干个环

要使得若干个环连成大环

令a[i]向b[i - 1] 连边

易证一定能使图联通

感性理解这也是最小的

#include<cstdio>
#include<algorithm>
using namespace std;
const int P = 32767;
int n, x, y, z, F[1000005];
struct node
{
	int val, id;
}a[1000005], b[1000005], e[1000005];
bool cmp(node a, node b)
{
	return a.val < b.val;
}
int find(int x)
{
	if (F[x] != x) F[x] = find(F[x]);
	return F[x];
}
int main()
{
	scanf("%d", &n);
	scanf("%d%d%d%d%d", &a[1].val, &a[2].val, &x, &y, &z);
	for (int i = 3; i <= n; i++) a[i].val = (1ll * x * a[i - 1].val + 1ll * y * a[i - 2].val + z) % P;
	scanf("%d%d%d%d%d", &b[1].val, &b[2].val, &x, &y, &z);
	for (int i = 3; i <= n; i++) b[i].val = (1ll * x * b[i - 1].val + 1ll * y * b[i - 2].val + z) % P;
	for (int i = 1; i <= n; i++) a[i].id = b[i].id = i;
	sort(a + 1, a + n + 1, cmp);
	sort(b + 1, b + n + 1, cmp);
	for (int i = 1; i <= n; i++) F[i] = i;
	int ans = 0;
	for (int i = 1; i <= n; i++)
	{
		int x = a[i].id, y = b[i].id;
		int fx = find(x), fy = find(y);
		F[fy] = fx;
		ans = max(ans, a[i].val * a[i].val - b[i].val * b[i].val);
	}
	for (int i = 2; i <= n; i++) e[i - 1] = (node){a[i].val * a[i].val - b[i - 1].val * b[i - 1].val, i};
	sort(e + 1, e + n, cmp);
	for (int i = 1; i < n; i++)
	{
		int x = a[e[i].id].id, y = b[e[i].id - 1].id;
		int fx = find(x), fy = find(y);
		if (fx != fy)
		{
			F[fy] = fx;
			ans = max(ans, e[i].val);
		}
	}
	printf("%d\n", ans);
	return 0;
}

  

posted @ 2019-03-22 22:22  ~Silent  阅读(174)  评论(0编辑  收藏  举报
Live2D