Submission #1295761

#TimeUsernameProblemLanguageResultExecution timeMemory
1295761mutammimSynchronization (JOI13_synchronization)C++20
Compilation error
0 ms0 KiB
#include<bits/stdc++.h> using namespace std; // Extra functionality : // *st.find_by_order(index) = value at index // st.order_of_key(value) = number of elements strictly less than value #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace __gnu_pbds; #define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> #define ll long long #define lld long double #define vll vector<long long> #define pll pair<long long, long long> #define vvll vector<vll> #define vvvll vector<vvll> #define ar array #define F first #define S second #define all(v) v.begin(),v.end() #define range(v, i, j) v.begin()+i, v.begin()+j+1 #define For(i, a, b) for(long long i = (a); i <= (b); ++(i)) #define L(i, a, b) for(long long i = (a); i <= (b); ++(i)) #define R(i, a, b) for(long long i = (a); i >= (b); --(i)) #define sz(x) (ll)(x.size()) #define extract(m, x) { auto it = (m).find(x); if (it != (m).end()) (m).erase(it); } // set, multiset, map #define gp " " #define nl "\n" #define yes cout<<"YES"<<nl #define no cout<<"NO"<<nl #define isSet(x, i) ((x>>i)&1) #define setbit(x, i) (x | (1LL<<i)) #define resetbit(x, i) (x & (~(1LL << i))) #define toggleBit(x, i) ((x) ^ (1LL << (i))) #define getBit(x, i) (((x) >> (i)) & 1) #define clz(x) __builtin_clzll(x) #define ctz(x) __builtin_ctzll(x) #define csb(x) __builtin_popcountll(x) #ifdef LOCAL #include "debug.h" #else #define deb(...) (void)0 #endif mt19937_64 rnd(chrono::steady_clock::now().time_since_epoch().count()); const int dx4[4] = {0, 0, 1, -1}, dy4[4] = {1, -1, 0, 0}; const int mod = 1e9 + 7; const int N = 200005; /////////////////////////////////////// const ll inf = 1e15; ///////////////////////////////////////////// struct Seg{ struct node{ ll mn = inf; ll mx = -inf; ll lazy = 0; // USE INF FOR RANGE ASSIGNMENT ***** ll sum = 0; node() {} node(ll x) : mn(x), mx(x), sum(x) {} void apply(int l, int r, ll y) { mn += y; mx += y; sum += y * (r - l + 1); if(l != r) lazy += y; // => applied here, but pending in children // mn = mx = y; // for range assignment // sum = y * (r - l + 1) // for range assignment // if(l != r) lazy = y; // for range assignment } }; int size; vector<node> tree; Seg(vll & a) { ll n = sz(a); size = 1; while(size < n) size *= 2; tree.assign(2 * size , node()); For(i, 0, n-1) { // leaves (input array) tree[size + i] = a[i]; } for(ll j = size - 1; j >= 1; j--) { pull(j); } } node unite(node a, node b){ node res; res.mn = min(a.mn, b.mn); res.mx = max(a.mx, b.mx); res.sum = a.sum + b.sum; return res; } void push(int pos, int l, int r){ if(l == r) return; if (tree[pos].lazy != 0) { // default lazy int mid = (l + r) / 2; tree[2*pos].apply(l, mid, tree[pos].lazy); tree[2*pos+1].apply(mid+1, r, tree[pos].lazy); tree[pos].lazy = 0; // default lazy } } void pull(int pos){ tree[pos] = unite(tree[pos * 2], tree[pos * 2 + 1]); } node query(int ql, int qr){ return query(1, 0, size-1, ql, qr); } node query(int pos, int l, int r, int ql, int qr) { push(pos, l, r); if (l >= ql && r <= qr) { return tree[pos];} if (qr < l || ql > r) return node(); int mid = (l + r) / 2; node res; if (qr <= mid) res = query(2 * pos, l, mid, ql, qr); else if (ql > mid) res = query(pos * 2 + 1, mid + 1, r, ql, qr); else res = unite(query(pos * 2, l, mid, ql, qr), query(pos * 2 + 1, mid + 1, r, ql, qr)); return res; } void modify(int ql, int qr, ll y) { modify(1, 0, size-1, ql, qr, y); } void modify(int pos, int l, int r, int ql, int qr, ll y){ if(ql > r || qr < l) return; push(pos, l, r); if (l >= ql && r <= qr){ tree[pos].apply(l, r, y); return; } int mid = (l + r) / 2; if (ql <= mid) modify(2 * pos, l, mid, ql, qr, y); if (qr > mid) modify(2 * pos + 1, mid + 1, r, ql, qr, y); pull(pos); } }; void prep(){ } ll n, m, x, y, z, q, k, u, v, w; vvll gr(N); vector<ar<ll,2>> edges(N); ll timer = -1; vll in(N), out(N); vvll lift(N, vll(20)); vll depth(N); void euler_tour(ll node, ll par, ll d) { depth[node] = d; lift[node][0] = par; for(ll j = 1; j < 20; ++j) { lift[node][j] = lift[ lift[node][j-1] ][j-1]; } in[node] = ++timer; for(ll ch : gr[node]) { if(ch == par) continue; euler_tour(ch, node, d+1); } out[node] = timer; } vll prevv(N), now(N, 1); bool ispres[N]; void solve(int tcase){ // testcases ? // cleanup ? cin >> n >> m >> q; L(i, 1, n-1) { cin >> u >> v; gr[u].push_back(v); gr[v].push_back(u); edges[i] = {u, v}; } euler_tour(1,0, 0); vll khali(n+1); Seg seg(khali); // will hold no. of DISCONNECTED edges on path to root L(i, 1, n) seg.modify(in[i], in[i], depth[i]); auto find_root = [&](ll y) { R(j,19,0) { ll x = lift[y][j]; ll disc_x = seg.query(in[x],in[x]).sum; // or min/max ll disc_y = seg.query(in[y],in[y]).sum; if(disc_y == disc_x) { // x is in y's component y = x; } } return y; }; ll e; while(m--) { cin >> e; auto [u, v] = edges[e]; if(!ispres[e]) { ispres[e] = 1; // make v the one below if(lift[u][0] == v) swap(u,v); ll root = find_root(u); now[root] += now[v] - prevv[v]; seg.modify(in[v], out[v], -1); } else { ispres[e] = 0; // make v the one below if(lift[u][0] == v) swap(u,v); ll root = find_root(v); // or u now[v] = now[root]; prevv[v] = now[v]; seg.modify(in[v], out[v], +1); } } while(q--) { cin >> u; cout << now[find_root(u)] << nl; } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); prep(); int tcase = 1; // int t; cin >> t; for(; tcase <= t; ++tcase) solve(tcase); }