Submission #377943

#TimeUsernameProblemLanguageResultExecution timeMemory
3779432qbingxuanMergers (JOI19_mergers)C++14
0 / 100
83 ms35604 KiB
#include <bits/stdc++.h> #ifdef local #define debug(a...) qqbx(#a, a) template <typename ...T> void qqbx(const char *s, T ...a) { int cnt = sizeof...(T); ((std::cerr << "\033[1;32m(" << s << ") = (") , ... , (std::cerr << a << (--cnt ? ", " : "\033[0m)\n"))); } #define safe std::cerr<<__PRETTY_FUNCTION__<<" line "<<__LINE__<<" safe\n" #else #define debug(...) ((void)0) #define safe ((void)0) #endif // local #define all(v) begin(v),end(v) #define pb emplace_back #define sort_uni(v) sort(all(v)), v.erase(unique(all(v)), v.end()) using namespace std; using ll = int64_t; template <typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>; const ll INF = 1e18; const int maxn = 500025, inf = 1e9; struct Segtree { int n; vector<int> st; function<int(int,int)> Func; int Id; Segtree(int _n, function<int(int,int)> f, int id) : n(_n), st(_n * 2, id), Func(f), Id(id) {} int& operator[](int idx) { return st[idx + n]; } void build() { for (int i = n-1; i > 0; i--) st[i] = Func(st[i<<1], st[i<<1|1]); } int query(int l, int r) { int res = Id; for (l += n, r += n; l < r; l >>= 1, r >>= 1) { if (l&1) res = Func(res, st[l++]); if (r&1) res = Func(res, st[--r]); } return res; } }; struct Dsu { vector<int> pa, rk; Dsu(int n) : pa(n), rk(n) { iota(all(pa), 0); } int anc(int x) { return x==pa[x] ? x : pa[x] = anc(pa[x]); } bool join(int x, int y) { if ((x=anc(x)) == (y=anc(y))) return false; if (rk[x] < rk[y]) swap(x, y); return pa[y] = x, rk[x] != rk[y] || ++rk[x]; } }; vector<int> g[maxn], adj[maxn]; int color[maxn]; int pa[maxn], in[maxn], ou[maxn], tot; int mn[maxn], mx[maxn]; void dfs(int i, int p) { pa[i] = p; in[i] = tot++; for (int j: g[i]) { if (j == p) continue; dfs(j, i); } ou[i] = tot; } signed main() { ios_base::sync_with_stdio(0), cin.tie(0); int n, k; cin >> n >> k; for (int i = 1; i < n; i++) { int a, b; cin >> a >> b; g[a].emplace_back(b); g[b].emplace_back(a); } for (int i = 1; i <= n; i++) cin >> color[i]; dfs(1, 0); for (int i = 1; i <= k; i++) mn[i] = inf, mx[i] = -inf; for (int i = 1; i <= n; i++) { int c = color[i]; mn[c] = min(mn[c], in[i]); mx[c] = max(mx[c], in[i]); } // qx <= x <= y <= qy // x <= qx <= qy <= y Segtree R(n, [](int a, int b){ return max(a, b); }, 0); Segtree L(n, [](int a, int b){ return min(a, b); }, inf); Dsu dsu(n + 1); for (int i = 1; i <= k; i++) { debug(mn[i], mx[i]); R[mn[i]] = max(R[mn[i]], mx[i]); L[mx[i]] = min(L[mx[i]], mn[i]); } R.build(); L.build(); for (int i = 1; i <= n; i++) { if (R.query(in[i], ou[i]) >= ou[i] || L.query(in[i], ou[i]) < in[i]) { debug(i, pa[i]); dsu.join(i, pa[i]); } } vector<int> deg(n + 1); for (int i = 1; i <= n; i++) { for (int j: g[i]) { int a = dsu.anc(i); int b = dsu.anc(j); if (a != b) adj[a].push_back(b); } } for (int i = 1; i <= n; i++) sort_uni(adj[i]); int leaf = 0; for (int i = 1; i <= n; i++) { int deg = adj[i].size(); debug(deg); if (deg == 1) ++leaf; } debug(leaf); cout << (leaf + 1) / 2 << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...