intmerge(int x, int y){ if (x == y) return x; if (!x || !y) return x | y; if (val[x] == val[y] ? x > y : val[x] > val[y]) swap(x, y); rs[x] = merge(rs[x], y); if (dis[ls[x]] < dis[rs[x]]) swap(ls[x], rs[x]); dis[x] = dis[rs[x]] + 1; return x; }
intmain(){ // 从头到尾也没有用到 dis 的数值,所以无需真的将 dis[0] 初始化为 -1 scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &val[i]), p[i] = i;
for (int i = 1, opt, x, y; i <= m; i++) { scanf("%d%d", &opt, &x); if (opt == 1) { scanf("%d", &y); if (val[x] == -1 || val[y] == -1) continue; x = find(x), y = find(y); p[x] = p[y] = merge(x, y); } else { if (val[x] == -1) { puts("-1"); continue; } printf("%d\n", val[x = find(x)]); val[x] = -1; p[ls[x]] = p[rs[x]] = p[x] = merge(ls[x], rs[x]); } } return0; }
Monkey King
曾经在一个森林中居住着 N 只好斗的猴子。在最初他们我行我素,互不认识。但是猴子们不能避免争吵,且两只猴子只会在不认识对方时发生争吵,当争吵发生时,双方会邀请它们各自最强壮的朋友并发起决斗(决斗的为各自最强壮的朋友)。当然,在决斗之后两只猴子和他们各自的伙伴都认识对方了(成为朋友),虽然他们曾经有过冲突,但是他们之间绝不会再发生争吵了。
intquery(int a, int b){ a = find(a), b = find(b); if (a == b) return-1; half(a), half(b); int res = max(val[a = find(a)], val[b = find(b)]); p[a] = p[b] = merge(a, b); return res; }
intmain(){ while (scanf("%d", &n) == 1) { for (int i = 1; i <= n; i++) scanf("%d", &val[i]), p[i] = i, ls[i] = rs[i] = 0; scanf("%d", &m); for (int i = 1, x, y; i <= m; i++) { scanf("%d%d", &x, &y); printf("%d\n", query(x, y)); } } return0; }
#define int long long #define eb emplace_back constint N = 100010; int n, m, ans, ls[N], dis[N], rs[N], val[N], sum[N], p[N], sz[N], l[N]; vector<int> g[N];
namespace IO { /* 省略 */ } using IO::read; using IO::write;
intmerge(int a, int b){ if (a == b) return a; if (!a || !b) return a | b; if (val[a] < val[b]) swap(a, b); rs[a] = merge(rs[a], b); if (dis[ls[a]] < dis[rs[a]]) swap(ls[a], rs[a]); dis[a] = dis[rs[a]] + 1; return a; }
voiddp(int u, int fa){ for (int to: g[u]) if (to != fa) dp(to, u); int f = find(u); while (sum[f] > m) { p[ls[f]] = p[rs[f]] = p[f] = merge(ls[f], rs[f]); sum[p[f]] = sum[f] - val[f]; sz[p[f]] = sz[f] - 1; f = p[f]; } int b = find(u); ans = max(ans, l[u] * sz[b]); if (fa) { int a = find(fa); p[a] = p[b] = merge(a, b); sz[p[a]] = sz[a] + sz[b]; sum[p[a]] = sum[a] + sum[b]; } }
signedmain(){ int rt = 0; read(n, m); for (int i = 1, fa; i <= n; i++) { read(fa, val[i], l[i]); if (!fa) rt = i; else g[i].eb(fa), g[fa].eb(i); p[i] = i, sum[i] = val[i], sz[i] = 1; } dp(rt, 0); returnwrite(ans), 0; }