Submission #1105500

#TimeUsernameProblemLanguageResultExecution timeMemory
1105500Zero_OPDigital Circuit (IOI22_circuit)C++17
100 / 100
1008 ms39884 KiB
#include <bits/stdc++.h> #ifndef LOCAL #include "circuit.h" #endif // LOCAL using namespace std; #define rep(i, l, r) for(int i = (l), _r = (r); i < _r; ++i) #define FOR(i, l, r) for(int i = (l), _r = (r); i <= _r; ++i) #define ROF(i, r, l) for(int i = (r), _l = (l); i >= _l; --i) #define all(v) begin(v), end(v) #define compact(v) v.erase(unique(all(v)), end(v)) #define sz(v) (int)v.size() #define dbg(x) "[" #x " = " << (x) << "]" #define file(name) if(fopen(name".inp", "r")) freopen(name".inp", "r", stdin), freopen(name".out", "w", stdout); template<typename T> bool minimize(T& a, const T& b){ if(a > b) return a = b, true; return false; } template<typename T> bool maximize(T& a, const T& b){ if(a < b) return a = b, true; return false; } using ll = long long; using ld = long double; mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); template<typename T> T random_int(T l, T r){ return uniform_int_distribution<T>(l, r)(rng); } template<typename T> T random_real(T l, T r){ return uniform_real_distribution<T>(l, r)(rng); } const int MAX = 2e5 + 5; const int mod = 1e9 + 2022; int n, m; vector<int> adj[MAX]; bool state[MAX]; int dp[MAX][2], total_ways[MAX], eval[MAX]; int add(int a, int b){ return a + b < mod ? a + b : a + b - mod; } int multiply(int a, int b){ return 1LL * a * b % mod; } int subtract(int a, int b){ return a < b ? a - b + mod : a - b; } bool isLeaf(int u){ return n <= u; } struct node{ int total, one; node(int total = 0, int one = 0) : total(total), one(one) {} void flip(){ one = subtract(total, one); } friend node operator + (const node& a, const node& b){ return node(add(a.total, b.total), add(a.one, b.one)); } }; namespace SegmentTree{ node st[MAX << 1]; int lazy[MAX << 1]; void build(int id, int l, int r){ if(l == r){ st[id] = node(eval[l], (int)state[l] * eval[l]); } else{ int mid = l + r >> 1; build(id << 1, l, mid); build(id << 1 | 1, mid + 1, r); st[id] = st[id << 1] + st[id << 1 | 1]; } } void apply(int id){ st[id].flip(); lazy[id] ^= 1; } void lazyDown(int id){ if(lazy[id]){ apply(id << 1); apply(id << 1 | 1); lazy[id] = 0; } } void update(int id, int l, int r, int u, int v){ if(u <= l && r <= v) apply(id); else{ int mid = l + r >> 1; lazyDown(id); if(u <= mid) update(id << 1, l, mid, u, v); if(mid < v) update(id << 1 | 1, mid + 1, r, u, v); st[id] = st[id << 1] + st[id << 1 | 1]; } } int get(){ return st[1].one; } } void predfs(int u){ if(isLeaf(u)){ total_ways[u] = 1; return; } total_ways[u] = sz(adj[u]); for(int v : adj[u]){ predfs(v); total_ways[u] = multiply(total_ways[u], total_ways[v]); } } void dfs(int u, int mult){ if(isLeaf(u)){ eval[u - n] = mult; return; } int k = sz(adj[u]); vector<int> pref(k), suff(k); for(int i = 0; i < k; ++i){ pref[i] = suff[i] = total_ways[adj[u][i]]; } for(int i = 1; i < k; ++i){ pref[i] = multiply(pref[i - 1], pref[i]); } for(int i = k - 2; i >= 0; --i){ suff[i] = multiply(suff[i], suff[i + 1]); } for(int i = 0; i < k; ++i){ int cur = multiply(i > 0 ? pref[i - 1] : 1, i + 1 < k ? suff[i + 1] : 1); dfs(adj[u][i], multiply(mult, cur)); } } void init(int N, int M, vector<int> P, vector<int> A){ n = N; m = M; rep(i, 1, n + m){ adj[P[i]].push_back(i); } rep(i, 0, m){ state[i] = A[i]; } predfs(0); dfs(0, 1); SegmentTree::build(1, 0, m - 1); } int count_ways(int L, int R){ L -= n; R -= n; SegmentTree::update(1, 0, m - 1, L, R); return SegmentTree::get(); } #ifdef LOCAL int main(){ srand(time(nullptr)); mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); auto random = [&](int l, int r){ return uniform_int_distribution<int>(l, r)(rng); }; for(int itest = 1; itest <= 1; ++itest){ //random testcase // int N = random(1, 6), M = random(1, 20), Q = random(1, 5); // cout << "N = " << N << ", M = " << M << ", Q = " << Q << '\n'; // vector<int> P(N + M, -1); // rep(i, 1, N + M){ // P[i] = random(0, min(i - 1, N - 1)); // } // // vector<int> A(M); // rep(i, 0, M){ // A[i] = random(0, 1); // } // cout << "Array P : "; rep(i, 0, N + M) cout << P[i] << ' '; cout << '\n'; // cout << "Array A : "; rep(i, 0, M) cout << A[i] << ' '; cout << '\n'; // init(N, M, P, A); // rep(i, 0, Q){ // int L = random(0, M - 1), R = random(0, M - 1); // if(L > R) swap(L, R); // cout << "query : " << L << ' ' << R << '\n'; // cout << count_ways(L, R) << '\n'; // } //example testcase int N = 3, M = 4; vector<int> P(N + M); P = {-1, 0, 1, 2, 1, 1, 0}; vector<int> A(M); A = {1, 0, 1, 0}; init(N, M, P, A); cout << count_ways(3, 4) << '\n'; //should be 2 cout << count_ways(4, 5) << '\n'; //should be 0 cout << count_ways(3, 6) << '\n'; //should 6 } return 0; } #endif //LOCAL

Compilation message (stderr)

circuit.cpp: In function 'bool minimize(T&, const T&)':
circuit.cpp:20:5: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
   20 |     if(a > b) return a = b, true; return false;
      |     ^~
circuit.cpp:20:35: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
   20 |     if(a > b) return a = b, true; return false;
      |                                   ^~~~~~
circuit.cpp: In function 'bool maximize(T&, const T&)':
circuit.cpp:25:5: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
   25 |     if(a < b) return a = b, true; return false;
      |     ^~
circuit.cpp:25:35: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
   25 |     if(a < b) return a = b, true; return false;
      |                                   ^~~~~~
circuit.cpp: In function 'void SegmentTree::build(int, int, int)':
circuit.cpp:77:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   77 |             int mid = l + r >> 1;
      |                       ~~^~~
circuit.cpp: In function 'void SegmentTree::update(int, int, int, int, int)':
circuit.cpp:100:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  100 |             int mid = l + r >> 1;
      |                       ~~^~~
#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...