Submission #1267350

#TimeUsernameProblemLanguageResultExecution timeMemory
1267350_filya_Synchronization (JOI13_synchronization)C++20
0 / 100
1887 ms26096 KiB
#include<bits/stdc++.h> typedef long long ll; using namespace std; const int N = 1e5 + 50; struct segtree { vector<long long> lazy, sum; int size = 1; void init(int n) { while (size < n) { size *= 2; } lazy.assign(2 * size - 1, 0ll); sum.assign(2 * size - 1, 0ll); } void prop(int x, int lx, int rx) { if (rx - lx == 1) { lazy[x] = 0; return; } lazy[2 * x + 1] += lazy[x]; lazy[2 * x + 2] += lazy[x]; sum[2 * x + 1] += lazy[x] * static_cast<long long>(rx - lx) / 2; sum[2 * x + 2] += lazy[x] * static_cast<long long>(rx - lx) / 2; lazy[x] = 0; } void add(int l, int r, ll v, int x, int lx, int rx) { if (lx >= l && rx <= r) { lazy[x] += v; sum[x] += v * static_cast<long long>(rx - lx); return; } if (rx <= l || lx >= r) { return; } int m = (rx + lx) / 2; add(l, r, v, 2 * x + 1, lx, m); add(l, r, v, 2 * x + 2, m, rx); sum[x] = sum[2 * x + 1] + sum[2 * x + 2] + lazy[x] * (rx - lx); } void add(int l, int r, ll val) { add(l, r, val, 0, 0, size); } ll query(ll l, ll r, int x, ll lx, ll rx) { prop(x, lx, rx); if (lx >= l && rx <= r) { return sum[x]; } if (rx <= l || lx >= r) { return 0ll; } int m = (rx + lx) / 2; ll s1 = query(l, r, 2 * x + 1, lx, m); ll s2 = query(l, r, 2 * x + 2, m, rx); return s1 + s2 + lazy[x] * (rx - lx); } ll query(ll l, ll r) { return query(l, r, 0, 0, size); } } tree1, tree2; int last[N], ans[N], par[N], root[N], depth[N], sz[N], pos[N], rpos[N], ti = 0; vector<int> G[N]; void dfsSz(int s, int p) { sz[s] = 1; depth[s] = depth[p] + 1; par[s] = p; if (root[s] == -1) root[s] = s; for (auto& u : G[s]) { if (u == p) continue; dfsSz(u, s); sz[s] += sz[u]; if (sz[u] > sz[G[s][0]]) swap(G[s][0], u); } } void dfsHld(int s, int p) { pos[s] = ++ti; rpos[ti] = s; for (auto u : G[s]) { if (u == p) continue; root[u] = (u == G[s][0] ? root[s] : u); dfsHld(u, s); } } int highest_ancesor(int u) { if (tree1.query(pos[root[u]], pos[u] + 1) == pos[u] - pos[root[u]]) { return root[u]; } int l = pos[root[u]] - 1, r = pos[u]; while(r - l > 1) { int mid = (r + l + 1) / 2; if (tree1.query(mid, pos[u] + 1) != pos[u] - mid) { l = mid; } else { r = mid; } } return rpos[r]; } void query1(int u) { int s = u; int dif = tree2.query(pos[s], pos[s] + 1) - last[s]; while(s != -1) { int h = highest_ancesor(s); tree2.add(pos[h], pos[s] + 1 - (s == u), dif); if (h != root[s] || !h || tree1.query(pos[h], pos[s] + 1) != pos[s] - pos[h] + 1) { break; } s = par[root[s]]; } } int query2(int s) { while(s != -1) { int h = highest_ancesor(s); if (h != root[s] || !h || tree1.query(pos[h], pos[s] + 1) != pos[s] - pos[h] + 1) { return h; } s = par[root[s]]; } return 0; } int main() { // ifstream cin("input.txt"); // ofstream cout("output.txt"); ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int n, m, q; cin >> n >> m >> q; vector<array<int, 2>> edges; for (int i = 0; i < n - 1; i++) { int u, v; cin >> u >> v; u--; v--; G[u].push_back(v); G[v].push_back(u); edges.push_back({u, v}); } dfsSz(0, -1); dfsHld(0, -1); tree1.init(n + 1); tree2.init(n + 1); for (int i = 0; i < n; i++) { ans[i] = 1; last[i] = 0; tree2.add(pos[i], pos[i] + 1, 1); } for (auto& e : edges) { if (e[0] == par[e[1]]) swap(e[0], e[1]); } while(m--) { int e; cin >> e; e--; auto [u, v] = edges[e]; if (tree1.query(pos[u], pos[u] + 1) == 0) { tree1.add(pos[u], pos[u] + 1, 1); query1(u); } else { int anc = query2(u); last[u] = tree2.query(pos[u], pos[u] + 1); ll pl = tree2.query(pos[anc], pos[anc] + 1) - last[u]; tree2.add(pos[u], pos[u] + 1, pl); tree1.add(pos[u], pos[u] + 1, -1); } } while(q--) { int u; cin >> u; u--; int anc = query2(u); cout << tree2.query(pos[anc], pos[anc] + 1) << '\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...