Submission #1255953

#TimeUsernameProblemLanguageResultExecution timeMemory
1255953kamradSynchronization (JOI13_synchronization)C++20
100 / 100
143 ms15292 KiB
#include <bits/stdc++.h> using namespace std; //#pragma GCC optimize("Ofast,unroll-loops") //pragma GCC target("avx2,popcnt,lzcnt,abm,bmi,bmi2,fma,tune=native") using ll = long long; using ld = long double; using pii = pair<int, int>; using pll = pair<ll, ll>; using pi3 = pair<pii, int>; #define IOS ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); #define F first #define S second #define sz(x) x.size() #define all(x) x.begin(), x.end() #define pb push_back #define cl clear #define minr(a, b) a = min(a, b); #define maxr(a, b) a = max(a, b); #define shit cout << "shit\n" << flush; #define tl while(1&1) continue; #define FOR(i, st, nd) for(int i = st; i <= n; i++) #define rand(l, r) uniform_int_distribution<int64_t>(l,r)(rng) random_device device; default_random_engine rng(device()); const int Mod = 1e9 + 7; //998244353; const int LG = 64; const int SQ = 500; const int Inf = 2e9 + 10; const int maxN = 1e5 + 10; int n, m, q; int tim = 1; int h[maxN]; int st[maxN]; int ft[maxN]; int cur[maxN]; int lst[maxN]; int stNode[maxN]; bool mark[maxN]; bool active[maxN]; vector <int> neighb[maxN]; vector <pii> edges; struct RootSegTree { struct Node { int MxR; Node() { MxR = 0; } } t[maxN<<2]; void initialize(int id, int L, int R) { if(L+1 == R) { t[id].MxR = ft[stNode[L]]; return; } int mid = (L+R)>>1; initialize(2*id+0, L, mid); initialize(2*id+1, mid, R); t[id].MxR = max(t[2*id+0].MxR, t[2*id+1].MxR); } void update(int id, int L, int R, int idx, int val) { if(L+1 == R) { t[id].MxR = val; return ; } int mid = (L+R)>>1; if(idx < mid) update(2*id+0, L, mid, idx, val); else update(2*id+1, mid, R, idx, val); t[id].MxR = max(t[2*id+0].MxR, t[2*id+1].MxR); } int search(int id, int L, int R, int val) { if(L+1 == R) return L; int mid = (L+R)>>1; if(t[2*id+1].MxR >= val) return search(2*id+1, mid, R, val); return search(2*id+0, L, mid, val); } int GetRoot(int id, int L, int R, int l, int r, int val) { if(t[id].MxR < val) return -1; if(L == l and R == r) return search(id, L, R, val); int mid = (L+R)>>1; if(r <= mid) return GetRoot(2*id+0, L, mid, l, min(mid, r), val); int tmp = GetRoot(2*id+1, mid, R, max(l, mid), r, val); if(tmp >= 1) return tmp; return GetRoot(2*id+0, L, mid, l, min(mid, r), val); } } rst; void dfs(int u) { st[u] = tim; stNode[tim] = u; tim++; mark[u] = true; for(auto v : neighb[u]) { if(!mark[v]) { dfs(v); } } ft[u] = tim-1; } int main() { IOS; int n, m, q; cin >> n >> m >> q; for(int i = 1; i <= n-1; i++) { int u, v; cin >> u >> v; neighb[u].pb(v); neighb[v].pb(u); edges.pb({u, v}); } dfs(1); rst.initialize(1, 1, n+1); for(int i = 1; i <= n; i++) cur[i] = 1; while(m--) { int idx; cin >> idx; int u = edges[idx-1].F; int v = edges[idx-1].S; if(st[u] > st[v]) swap(u, v); if(active[idx]) { active[idx] = false; int root = rst.GetRoot(1, 1, n+1, 1, st[v]+1, st[v]); rst.update(1, 1, n+1, st[v], ft[v]); cur[v] = cur[stNode[root]]; lst[v] = cur[v]; } else { active[idx] = true; int root = rst.GetRoot(1, 1, n+1, 1, st[u]+1, st[u]); rst.update(1, 1, n+1, st[v], 0); cur[stNode[root]] += (cur[v]-lst[v]); } } while(q--) { int u; cin >> u; int root = rst.GetRoot(1, 1, n+1, 1, st[u]+1, st[u]); cout << cur[stNode[root]] << "\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...