Submission #245250

#TimeUsernameProblemLanguageResultExecution timeMemory
245250Tc14Railway (BOI17_railway)C++17
100 / 100
249 ms39984 KiB
//#pragma GCC optimize("O3") #include <bits/stdc++.h> using namespace std; #define ve vector struct SegmentTree { int Cap; ve<int> Seg; void build(int n) { Cap = 1 << (int)ceil(log2(n)); Seg = ve<int>(2 * Cap); } int left(int i) { return 2 * i; } int right(int i) { return 2 * i + 1; } int parent(int i) { return i / 2; } int query(int x) { int curr, r; curr = Cap + x; r = 0; while (curr != 0) { r += Seg[curr]; curr = parent(curr); } return r; } void rangeUpdate(int a, int b, int x) { update(a, b, 0, Cap - 1, x, 1); } void update(int a, int b, int i, int j, int x, int curr) { int m; if (a <= i && j <= b) { Seg[curr] += x; return; } if (j < a || b < i) return; m = (i + j) / 2; update(a, b, i, m, x, left(curr)); update(a, b, m + 1, j, x, right(curr)); } }; int L, C; ve<int> Depth, Size, Jobs; ve<pair<int, int>> Comp; ve<ve<pair<int, int>>> Graph, Intervals; ve<ve<int>> Ancestor, CompVertecies, CompEdges; ve<SegmentTree> SegTrees; void dfs(int u, int p, int d) { int v, a; Depth[u] = d; a = p; for (int i = 0; i < L; i++) { Ancestor[u][i] = a; if (a != -1) a = Ancestor[a][i]; } Size[u] = 1; for (pair<int, int> e : Graph[u]) { v = e.first; if (v != p) { dfs(v, u, d + 1); Size[u] += Size[v]; } } } tuple<int, int, int> lca(int a, int b) { int ha, hb; ha = 0; hb = 0; if (Depth[a] > Depth[b]) { for (int i = L - 1; i >= 0; i--) { if (Depth[a] - (1 << i) >= Depth[b]) { a = Ancestor[a][i]; ha += 1 << i; } } } else { for (int i = L - 1; i >= 0; i--) { if (Depth[b] - (1 << i) >= Depth[a]) { b = Ancestor[b][i]; hb += 1 << i; } } } if (a == b) return {a, ha, hb}; else { for (int i = L - 1; i >= 0; i--) { if (Ancestor[a][i] != Ancestor[b][i]) { a = Ancestor[a][i]; b = Ancestor[b][i]; ha += 1 << i; hb += 1 << i; } } ha++; hb++; return {Ancestor[a][0], ha, hb}; } } void hld(int u, int p, int c) { int v, sizeMax, k; Comp[u] = {c, CompVertecies[c].size()}; CompVertecies[c].push_back(u); sizeMax = 0; k = -1; for (pair<int, int> e : Graph[u]) { v = e.first; if (v != p) { if (sizeMax < Size[v]) { sizeMax = Size[v]; k = v; } } } for (pair<int, int> e : Graph[u]) { v = e.first; if (v != p) { if (v == k) { CompEdges[c].push_back(e.second); hld(v, u, c); } else { C++; CompVertecies[C - 1].push_back(u); CompEdges[C - 1].push_back(e.second); hld(v, u, C - 1); } } } } void apply(int u, int h) { int c, d, a, b; while (h != 0) { tie(c, d) = Comp[u]; if (d >= h) { a = d - h; h = 0; } else { a = 0; h -= d; u = CompVertecies[c][0]; } b = d - 1; Intervals[c].push_back({a, b}); Jobs.push_back(c); } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n, m, k, a, b, s, t, tNew, u, hu, ht, aNew, bNew, ans; ve<int> Solution; cin >> n >> m >> k; L = ceil(log2(n)); Depth = ve<int>(n); Size = ve<int>(n); Comp = ve<pair<int, int>>(n); Graph = ve<ve<pair<int, int>>>(n); Ancestor = ve<ve<int>>(n, ve<int>(L)); CompVertecies = ve<ve<int>>(n); CompEdges = ve<ve<int>>(n); Intervals = ve<ve<pair<int, int>>>(n); for (int i = 0; i < n - 1; i++) { cin >> a >> b; a--; b--; Graph[a].push_back({b, i}); Graph[b].push_back({a, i}); } dfs(0, -1, 0); C = 0; for (pair<int, int> e : Graph[0]) { C++; CompVertecies[C - 1].push_back(0); CompEdges[C - 1].push_back(e.second); hld(e.first, 0, C - 1); } SegTrees = vector<SegmentTree>(C); for (int i = 0; i < C; i++) { SegTrees[i].build(CompEdges[i].size()); } for (int i = 0; i < m; i++) { cin >> s; cin >> t; t--; for (int j = 1; j < s; j++) { cin >> u; u--; tie(tNew, hu, ht) = lca(u, t); apply(u, hu); apply(t, ht); t = tNew; } for (int j : Jobs) { if (Intervals[j].size() > 0) { sort(Intervals[j].begin(), Intervals[j].end()); tie(a, b) = Intervals[j][0]; for (int l = 1; l < Intervals[j].size(); l++) { tie(aNew, bNew) = Intervals[j][l]; if (aNew <= b) b = max(b, bNew); else { SegTrees[j].rangeUpdate(a, b, 1); a = aNew; b = bNew; } } SegTrees[j].rangeUpdate(a, b, 1); Intervals[j].clear(); } } Jobs.clear(); } ans = 0; for (int i = 0; i < C; i++) { for (int j = 0; j < CompEdges[i].size(); j++) { if (SegTrees[i].query(j) >= k) { Solution.push_back(CompEdges[i][j]); ans++; } } } sort(Solution.begin(), Solution.end()); cout << ans << endl; for (int i = 0; i < ans; i++) { cout << Solution[i] + 1 << " "; } cout << endl; return 0; }

Compilation message (stderr)

railway.cpp: In function 'int main()':
railway.cpp:241:35: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
                 for (int l = 1; l < Intervals[j].size(); l++) {
                                 ~~^~~~~~~~~~~~~~~~~~~~~
railway.cpp:259:27: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (int j = 0; j < CompEdges[i].size(); j++) {
                         ~~^~~~~~~~~~~~~~~~~~~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...