Submission #1212269

#TimeUsernameProblemLanguageResultExecution timeMemory
1212269mmario99Digital Circuit (IOI22_circuit)C++20
100 / 100
343 ms27784 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; static const ll MOD = 1000002022; static int gN, gM; static vector<int> parentArr; static vector<vector<int>> children; static vector<ll> Sval; static vector<ll> Wval; static vector<ll> upVal; static vector<ll> coef; static vector<int> leafState; struct SegTree { int n; struct Node { ll sum; ll totCoef; bool flip; }; vector<Node> st; SegTree(int _n = 0) : n(_n) { if (n > 0) st.resize(4 * n); } void build(int p, int l, int r) { if (l == r) { st[p].totCoef = coef[l] % MOD; st[p].sum = (coef[l] * leafState[l]) % MOD; st[p].flip = false; return; } int m = (l + r) >> 1; build(p << 1, l, m); build(p << 1 | 1, m + 1, r); st[p].totCoef = (st[p << 1].totCoef + st[p << 1 | 1].totCoef) % MOD; st[p].sum = (st[p << 1].sum + st[p << 1 | 1].sum) % MOD; st[p].flip = false; } inline void applyFlip(int p) { st[p].sum = (st[p].totCoef - st[p].sum) % MOD; if (st[p].sum < 0) st[p].sum += MOD; st[p].flip = !st[p].flip; } inline void push(int p) { if (!st[p].flip) return; applyFlip(p << 1); applyFlip(p << 1 | 1); st[p].flip = false; } void updateRange(int p, int l, int r, int i, int j) { if (j < l || i > r) return; if (l >= i && r <= j) { applyFlip(p); return; } push(p); int m = (l + r) >> 1; updateRange(p << 1, l, m, i, j); updateRange(p << 1 | 1, m + 1, r, i, j); st[p].sum = (st[p << 1].sum + st[p << 1 | 1].sum) % MOD; } void init_build(int _n) { n = _n; st.resize(4 * n); build(1, 0, n - 1); } void invertInterval(int L, int R) { updateRange(1, 0, n - 1, L, R); } ll queryAll() const { return st[1].sum; } }; static SegTree seg; void init(int N, int M, std::vector <int> P, std::vector <int> A) { gN = N; gM = M; parentArr.resize(N + M); for (int i = 0; i < N + M; i++) { parentArr[i] = P[i]; } children.assign(N + M, {}); for (int i = 1; i < N + M; i++) { int p = parentArr[i]; children[p].push_back(i); } leafState.resize(M); for (int i = 0; i < M; i++) { leafState[i] = A[i]; } Sval.assign(N + M, 0LL); for (int v = N + M - 1; v >= 0; v--) { if (v >= N) { // Leaf Sval[v] = 1; } else { ll prod = 1; int d = (int)children[v].size(); for (int c : children[v]) { prod = (prod * Sval[c]) % MOD; } prod = (prod * d) % MOD; Sval[v] = prod; } } Wval.assign(N + M, 1LL); for (int v = 0; v < N; v++) { int d = (int)children[v].size(); if (d == 0) continue; vector<ll> pref(d), suf(d); for (int i = 0; i < d; i++) { pref[i] = Sval[children[v][i]]; suf[i] = pref[i]; } for (int i = 1; i < d; i++) { pref[i] = (pref[i] * pref[i - 1]) % MOD; } for (int i = d - 2; i >= 0; i--) { suf[i] = (suf[i] * suf[i + 1]) % MOD; } for (int i = 0; i < d; i++) { ll left = (i > 0 ? pref[i - 1] : 1LL); ll right = (i + 1 < d ? suf[i + 1] : 1LL); ll w = (left * right) % MOD; int c = children[v][i]; Wval[c] = w; } } Wval[0] = 1; upVal.assign(N + M, 1LL); vector<int> bfs; bfs.reserve(N + M); bfs.push_back(0); for (int idx = 0; idx < (int)bfs.size(); idx++) { int v = bfs[idx]; for (int c : children[v]) { upVal[c] = (upVal[v] * Wval[c]) % MOD; bfs.push_back(c); } } coef.assign(M, 0LL); for (int i = 0; i < M; i++) { coef[i] = upVal[N + i]; } seg = SegTree(M); seg.init_build(M); } int count_ways(int L, int R) { int l = L - gN; int r = R - gN; seg.invertInterval(l, r); ll ans = seg.queryAll() % MOD; return int(ans); }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...