QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#800744 | #9655. Divide a Tree | ucup-team004 | AC ✓ | 269ms | 26936kb | C++23 | 6.4kb | 2024-12-06 15:14:29 | 2024-12-06 15:14:29 |
Judging History
answer
#include <bits/stdc++.h>
using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
using u128 = unsigned __int128;
template <typename T>
struct Fenwick {
int n;
std::vector<T> a;
Fenwick(int n_ = 0) {
init(n_);
}
void init(int n_) {
n = n_;
a.assign(n, T{});
}
void add(int x, const T &v) {
for (int i = x + 1; i <= n; i += i & -i) {
a[i - 1] = a[i - 1] + v;
}
}
T sum(int x) {
T ans{};
for (int i = x; i > 0; i -= i & -i) {
ans = ans + a[i - 1];
}
return ans;
}
T rangeSum(int l, int r) {
return sum(r) - sum(l);
}
int select(const T &k) {
int x = 0;
T cur{};
for (int i = 1 << std::__lg(n); i; i /= 2) {
if (x + i <= n && cur + a[x + i - 1] <= k) {
x += i;
cur = cur + a[x - 1];
}
}
return x;
}
};
struct HLD {
int n;
std::vector<int> siz, top, dep, parent, in, out, seq;
std::vector<std::vector<int>> adj;
int cur;
HLD() {}
HLD(int n) {
init(n);
}
void init(int n) {
this->n = n;
siz.resize(n);
top.resize(n);
dep.resize(n);
parent.resize(n);
in.resize(n);
out.resize(n);
seq.resize(n);
cur = 0;
adj.assign(n, {});
}
void addEdge(int u, int v) {
adj[u].push_back(v);
adj[v].push_back(u);
}
void work(int root = 0) {
top[root] = root;
dep[root] = 0;
parent[root] = -1;
dfs1(root);
dfs2(root);
}
void dfs1(int u) {
if (parent[u] != -1) {
adj[u].erase(std::find(adj[u].begin(), adj[u].end(), parent[u]));
}
siz[u] = 1;
for (auto &v : adj[u]) {
parent[v] = u;
dep[v] = dep[u] + 1;
dfs1(v);
siz[u] += siz[v];
if (siz[v] > siz[adj[u][0]]) {
std::swap(v, adj[u][0]);
}
}
}
void dfs2(int u) {
in[u] = cur++;
seq[in[u]] = u;
for (auto v : adj[u]) {
top[v] = v == adj[u][0] ? top[u] : v;
dfs2(v);
}
out[u] = cur;
}
int lca(int u, int v) {
while (top[u] != top[v]) {
if (dep[top[u]] > dep[top[v]]) {
u = parent[top[u]];
} else {
v = parent[top[v]];
}
}
return dep[u] < dep[v] ? u : v;
}
int dist(int u, int v) {
return dep[u] + dep[v] - 2 * dep[lca(u, v)];
}
int jump(int u, int k) {
if (dep[u] < k) {
return -1;
}
int d = dep[u] - k;
while (dep[top[u]] > d) {
u = parent[top[u]];
}
return seq[in[u] - dep[u] + d];
}
bool isAncester(int u, int v) {
return in[u] <= in[v] && in[v] < out[u];
}
int rootedParent(int u, int v) {
std::swap(u, v);
if (u == v) {
return u;
}
if (!isAncester(u, v)) {
return parent[u];
}
auto it = std::upper_bound(adj[u].begin(), adj[u].end(), v, [&](int x, int y) {
return in[x] < in[y];
}) - 1;
return *it;
}
int rootedSize(int u, int v) {
if (u == v) {
return n;
}
if (!isAncester(v, u)) {
return siz[v];
}
return n - siz[rootedParent(u, v)];
}
int rootedLca(int a, int b, int c) {
return lca(a, b) ^ lca(b, c) ^ lca(c, a);
}
};
void solve() {
int N;
std::cin >> N;
std::vector<int> a(N);
for (int i = 0; i < N; i++) {
std::cin >> a[i];
a[i]--;
}
HLD t(N);
for (int i = 1; i < N; i++) {
int u, v;
std::cin >> u >> v;
u--;
v--;
t.addEdge(u, v);
}
t.work();
std::vector<std::vector<int>> vec(N);
for (int i = 0; i < N; i++) {
vec[a[i]].push_back(i);
}
std::vector<int> dp(N);
std::vector<std::vector<std::vector<std::array<int, 2>>>> comp(N);
for (int c = 0; c < N; c++) {
if (vec[c].empty()) {
continue;
}
auto &a = vec[c];
std::sort(a.begin(), a.end(),
[&](int x, int y) {
return t.in[x] < t.in[y];
});
int m = a.size();
for (int i = 1; i < m; i++) {
a.push_back(t.lca(a[i - 1], a[i]));
}
std::sort(a.begin(), a.end(),
[&](int x, int y) {
return t.in[x] < t.in[y];
});
a.erase(std::unique(a.begin(), a.end()), a.end());
std::vector<std::array<int, 2>> edges;
std::vector<int> stk;
for (auto x : a) {
if (stk.empty()) {
stk.push_back(x);
} else {
while (!t.isAncester(stk.back(), x)) {
stk.pop_back();
}
edges.push_back({stk.back(), x});
}
}
comp[a[0]].push_back(std::move(edges));
}
std::vector<int> g(N);
Fenwick<int> fen(N);
auto dfs = [&](auto &&self, int x) -> void {
for (auto y : t.adj[x]) {
self(self, y);
g[x] += dp[y];
}
dp[x] = g[x];
for (const auto &e : comp[x]) {
int res = 1 + g[x];
for (auto [u, v] : e) {
res += fen.sum(t.in[v] + 1);
res -= fen.sum(t.in[u] + 1);
}
dp[x] = std::max(dp[x], res);
}
fen.add(t.in[x], g[x] - dp[x]);
if (t.out[x] < N) {
fen.add(t.out[x], -g[x] + dp[x]);
}
};
dfs(dfs, 0);
std::cout << dp[0] << "\n";
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
std::cin >> t;
for (int i = 1; i <= t; i++) {
std::cout << "Case " << i << ": ";
solve();
}
return 0;
}
这程序好像有点Bug,我给组数据试试?
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 269ms
memory: 26936kb
input:
100 10 3 4 5 2 1 3 1 4 5 2 7 5 5 8 4 10 6 1 2 8 1 2 9 1 10 2 3 9 5 2 1 2 1 1 5 4 2 3 3 4 1 3 10 1 1 2 2 3 3 4 4 5 5 4 2 1 2 1 5 6 2 1 3 8 10 9 7 8 2 1 7 8 1 2 3 4 3 4 1 2 1 7 2 8 3 8 4 2 8 6 8 1 3 5 5 2 2 3 2 2 2 5 1 2 1 4 1 3 8 1 1 2 2 3 3 4 4 1 5 1 3 4 2 1 7 8 2 6 2 1 2 10 2 5 1 5 4 3 3 1 2 4 8 3 ...
output:
Case 1: 5 Case 2: 1 Case 3: 1 Case 4: 3 Case 5: 2 Case 6: 1 Case 7: 4 Case 8: 2 Case 9: 1 Case 10: 27 Case 11: 12 Case 12: 2 Case 13: 30 Case 14: 10 Case 15: 1 Case 16: 25 Case 17: 8 Case 18: 1 Case 19: 22 Case 20: 18 Case 21: 2 Case 22: 20 Case 23: 4 Case 24: 1 Case 25: 28 Case 26: 12 Case 27: 1 Ca...
result:
ok 100 lines
Extra Test:
score: 0
Extra Test Passed