int fst[100005], lst[100005], a[100005], c[200005], d[200005], S; int cnt, Cnt[100005], Cnt2[100005], id, now, ans[100005], fa[100005][19], dep[100005]; int nmsl[100005]; std::map<int, int> mp;//离散化 structEdge { int to, nxt; } e[200005]; int head[100005], tot; inlinevoidAddEdge(int u, int v){ e[++ tot].to = v, e[tot].nxt = head[u], head[u] = tot; } structQuest { int l, r, lca, id; inlinebooloperator < (const Quest x) { return (l - 1) / S == (x.l - 1) / S ? r < x.r : (l - 1) / S < (x.l - 1) / S; } } q[100005];
voiddfs(int u){ for (int i = 1; i <= 18; ++ i) fa[u][i] = fa[fa[u][i - 1]][i - 1]; dep[u] = dep[fa[u][0]] + 1, fst[u] = ++ cnt, d[cnt] = u; int t; if (!mp.count(a[u])) t = mp[a[u]] = ++ id; else t = mp[a[u]]; c[cnt] = nmsl[u] = t;//nmsl[u]记点u离散化后的值 for (int i = head[u]; i; i = e[i].nxt) if (e[i].to != fa[u][0]) fa[e[i].to][0] = u, dfs(e[i].to); lst[u] = ++ cnt, d[cnt] = u, c[cnt] = t; } inlineintquery(int u, int v){ if (dep[u] < dep[v]) u ^= v ^= u ^= v; for (int i = 0; i <= 18; ++ i) if (dep[u] - dep[v] & 1 << i) u = fa[u][i]; if (u == v) return u; for (int i = 18; i >= 0; -- i) if (fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i]; return fa[u][0]; } inlinevoidshabi(int x){ Cnt2[d[x]] ^= 1; if (Cnt2[d[x]] && ++ Cnt[c[x]] == 1) ++ now; if (!Cnt2[d[x]] && !(-- Cnt[c[x]])) -- now; }
intmain(){ int n, m, l = 1, r = 0; scanf("%d%d", &n, &m); S = 2 * n / sqrt(m); for (int i = 1; i <= n; ++ i) scanf("%d", a + i); for (int i = 1; i < n; ++ i) { int u, v; scanf("%d%d", &u, &v); AddEdge(u, v), AddEdge(v, u); } dfs(1); for (int i = 1; i <= m; ++ i) { int u, v, lca; scanf("%d%d", &u, &v); if (fst[u] > fst[v]) u ^= v ^= u ^= v; lca = query(u, v), q[i].id = i, q[i].lca = lca; if (lca == u) q[i].l = fst[u], q[i].r = fst[v]; else q[i].l = lst[u], q[i].r = fst[v]; } std::sort(q + 1, q + m + 1); for (int i = 1; i <= m; ++ i) { while (r < q[i].r) shabi(++ r); while (r > q[i].r) shabi(r --); while (l < q[i].l) shabi(l ++); while (l > q[i].l) shabi(-- l); ans[q[i].id] = now + (Cnt[nmsl[q[i].lca]] == 0); } for (int i = 1; i <= m; ++ i) printf("%d\n", ans[i]); return0; }
#include<cstdio> #include<map> #include<cmath> #include<algorithm> #include<cstring> #define int long long
inlineintmax(constint x, constint y){return x > y ? x : y;} std::map<int, int> mp; int a[100005], x[100005], ans[100005], cnt[100005], cnt2[100005], S, id, now; structQuest { int l, r, id; inlinebooloperator < (const Quest x) const { return (l - 1) / S == (x.l - 1) / S ? r < x.r : (l - 1) / S < (x.l - 1) / S; } } q[100005];
signedmain(){ int n, m; scanf("%lld%lld", &n, &m); S = n / sqrt(m); for (int i = 1; i <= n; ++ i) scanf("%lld", x + i); for (int i = 1; i <= n; ++ i) if (!mp.count(x[i])) a[i] = mp[x[i]] = ++ id; else a[i] = mp[x[i]]; for (int i = 1; i <= m; ++ i) scanf("%lld%lld", &q[i].l, &q[i].r), q[i].id = i; std::sort(q + 1, q + m + 1); for (int i = 1; i <= m;) { int blk = (q[i].l - 1) / S + 1, l = blk * S + 1, r = blk * S, lst = 0; memset(cnt, 0, sizeof cnt); for (; i <= m && blk == (q[i].l - 1) / S + 1; ++ i) {//一口气处理左端点在一个块里的询问 if (q[i].r <= blk * S) {//直接暴力 int now = 0; for (int k = q[i].l; k <= q[i].r; ++ k) cnt2[a[k]] = 0; for (int k = q[i].l; k <= q[i].r; ++ k) now = max(now, x[k] * (++ cnt2[a[k]])); ans[q[i].id] = now; } else { while (l <= blk * S) -- cnt[a[l ++]];//回滚左端点到p now = lst; while (r < q[i].r) ++ r, now = max(now, x[r] * (++ cnt[a[r]]));//调整右端点,更新lst lst = now; while (l > q[i].l) -- l, now = max(now, x[l] * (++ cnt[a[l]]));//调整左端点 ans[q[i].id] = now; } } } for (int i = 1; i <= m; ++ i) printf("%lld\n", ans[i]); return0; }
inlineintmax(constint x, constint y){return x > y ? x : y;} int fa[50005], a[50005], ans[50005], sze[50005], s[50005], top, n, m, S, now; int fa2[50005], sz2[50005]; structQuest { int l, r, id; inlinebooloperator < (const Quest a) const { return (l - 1) / S == (a.l - 1) / S ? r < a.r : (l - 1) / S < (a.l - 1) / S; } } q[50005]; intfind(int x){return fa[x] == x ? x : find(fa[x]);} inlinevoidmerge(int x, int y, bool flag = false){ x = find(x), y = find(y); if (x == y) return; if (sze[x] < sze[y]) x ^= y ^= x ^= y; fa[y] = x, now = max(now, (sze[x] += sze[y]) - 1); if (flag) s[++ top] = y; }
intmain(){ scanf("%d%d", &n, &m); S = n / sqrt(m); for (int i = 1; i <= n; ++ i) scanf("%d", a + i); for (int i = 1; i <= m; ++ i) scanf("%d%d", &q[i].l, &q[i].r), q[i].id = i; std::sort(q + 1, q + m + 1); for (int i = 1; i <= m;) { for (int j = 1; j <= n + 1; ++ j) fa[j] = j, sze[j] = 1; for (int j = 1; j <= n + 1; ++ j) fa2[j] = j, sz2[j] = 1; int blk = (q[i].l - 1) / S + 1, l = blk * S + 1, r = blk * S, lst = 0; top = 0; for (; (q[i].l - 1) / S + 1 == blk; ++ i) { if (q[i].r <= blk * S) { now = 0; for (int k = q[i].l; k <= q[i].r; ++ k) merge(a[k], a[k] + 1); ans[q[i].id] = now; for (int k = q[i].l; k <= q[i].r; ++ k) fa[a[k]] = a[k], sze[a[k]] = sze[a[k] + 1] = 1, fa[a[k] + 1] = a[k] + 1; } else { l = blk * S + 1; while (top) { sze[fa[s[top]]] -= sze[s[top]]; fa[s[top]] = s[top]; -- top; } now = lst; while (r < q[i].r) ++ r, merge(a[r], a[r] + 1); lst = now; while (l > q[i].l) -- l, merge(a[l], a[l] + 1, true); ans[q[i].id] = now; } } } for (int i = 1; i <= m; ++ i) printf("%d\n", ans[i]); return0; }
#include<cstdio> #include<algorithm> #include<vector> #include<map> #include<cmath> #define int long long
int fst[100005], lst[100005], a[100005], b[200005], pre[100005], S; int cnt, Cnt[100005], Cnt2[100005], id, now, ans[100005], fa[100005][19], dep[100005]; int v[100005], w[100005], Old[200005], New[200005], p[100005]; int l = 1, r, t; structEdge { int to, nxt; } e[200005]; int head[100005], tot; inlinevoidAddEdge(int u, int v){ e[++ tot].to = v, e[tot].nxt = head[u], head[u] = tot; } structQuest { int l, r, lca, id, t; inlinebooloperator < (const Quest x) const { int lb = (l - 1) / S, lb2 = (x.l - 1) / S, rb = (r - 1) / S, rb2 = (x.r - 1) / S; return lb == lb2 ? (rb == rb2 ? t < x.t : rb < rb2) : lb < lb2; } } q[100005];
voiddfs(int u){ for (int i = 1; i <= 18; ++ i) fa[u][i] = fa[fa[u][i - 1]][i - 1]; dep[u] = dep[fa[u][0]] + 1, fst[u] = ++ cnt, b[cnt] = u; for (int i = head[u]; i; i = e[i].nxt) if (e[i].to != fa[u][0]) fa[e[i].to][0] = u, dfs(e[i].to); lst[u] = ++ cnt, b[cnt] = u; } intquery(int u, int v){ if (dep[u] < dep[v]) u ^= v ^= u ^= v; for (int i = 0; i <= 18; ++ i) if (dep[u] - dep[v] & 1 << i) u = fa[u][i]; if (u == v) return u; for (int i = 18; i >= 0; -- i) if (fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i]; return fa[u][0]; } inlinevoidadd(int x){ int c = a[x]; Cnt2[x] ^= 1; if (!Cnt2[x]) now -= v[c] * w[Cnt[c] --]; if (Cnt2[x] && ++ Cnt[c] > 0) now += v[c] * w[Cnt[c]]; } inlinevoiddel(int x){ int c = a[x]; Cnt2[x] ^= 1; if (!Cnt2[x]) now -= v[c] * w[Cnt[c] --]; if (Cnt2[x] && ++ Cnt[c] > 0) now += v[c] * w[Cnt[c]]; } voidmodify(int p, int x){ if (Cnt2[p]) del(p), a[p] = x, add(p); a[p] = x; }
signedmain(){ int n, m, Q, qt = 0; scanf("%lld%lld%lld", &n, &m, &Q); S = pow(n, 2.0 / 3.0) * sqrt(2); for (int i = 1; i <= m; ++ i) scanf("%lld", v + i); for (int i = 1; i <= n; ++ i) scanf("%lld", w + i); for (int i = 1; i < n; ++ i) { int u, v; scanf("%lld%lld", &u, &v); AddEdge(u, v), AddEdge(v, u); } for (int i = 1; i <= n; ++ i) scanf("%lld", a + i), pre[i] = a[i]; dfs(1); for (int i = 1, j = 0; i <= Q; ++ i) { int opt; scanf("%lld", &opt); if (opt == 1) { int u, v, lca; scanf("%lld%lld", &u, &v); if (fst[u] > fst[v]) u ^= v ^= u ^= v; lca = query(u, v), q[++ qt].id = qt, q[qt].t = j; if (lca == u) q[qt].l = fst[u], q[qt].r = fst[v]; else q[qt].l = lst[u], q[qt].r = fst[v], q[qt].lca = lca; } else { int x, y; scanf("%lld%lld", &x, &y); Old[++ j] = pre[x], New[j] = pre[x] = y, p[j] = x; } } std::sort(q + 1, q + qt + 1); for (int i = 1; i <= qt; ++ i) { while (l > q[i].l) add(b[-- l]); while (r < q[i].r) add(b[++ r]); while (r > q[i].r) del(b[r --]); while (l < q[i].l) del(b[l ++]); while (t < q[i].t) ++ t, modify(p[t], New[t]); while (t > q[i].t) modify(p[t], Old[t]), t --; if (q[i].lca) ans[q[i].id] = v[a[q[i].lca]] * w[Cnt[a[q[i].lca]] + 1]; ans[q[i].id] += now; } for (int i = 1; i <= qt; ++ i) printf("%lld\n", ans[i]); return0; }