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; }