Submission #786451

#TimeUsernameProblemLanguageResultExecution timeMemory
786451vjudge1Digital Circuit (IOI22_circuit)C++17
18 / 100
850 ms7752 KiB
#include "circuit.h" #include <bits/stdc++.h> using namespace std; constexpr int mod = 1000002022; int N, M; vector<int> P, A, st, lazy, len; vector<vector<int>> ch; int add(int a, int b) { int c = a + b; if (c >= mod) { c -= mod; } return c; } int mul(int a, int b) { return 1LL * a * b % mod; } int sub(int a, int b) { int c = a - b; if (c < 0) { c += mod; } return c; } int cont; bool bintree; void apply(int p, int z) { if (z == 0) { return; } st[p] = len[p] - st[p]; lazy[p] ^= 1; } void pull(int p) { st[p] = st[p * 2] + st[p * 2 + 1]; } void push(int p) { apply(p * 2, lazy[p]); apply(p * 2 + 1, lazy[p]); lazy[p] = 0; } void update(int p, int l, int r, int L, int R) { if (R <= l || r <= L) { return; } if (L <= l && r <= R) { apply(p, 1); return; } int m = (l + r) / 2; push(p); update(p * 2, l, m, L, R); update(p * 2 + 1, m, r, L, R); pull(p); } void init(int n, int m, vector<int> p, vector<int> a) { N = n, M = m; P = p, A = a; ch.resize(N); for (int i = 1; i < N + M; i++) { ch[P[i]].push_back(i); } bintree = 0; if (N + 1 == M && __builtin_popcount(M) == 1) { bintree = 1; for (int i = 1; i < N + M; i++) { if (P[i] != (i - 1) / 2) { bintree = 0; } } if (bintree) { int lg = __lg(M); cont = 1; int s = 1; for (int i = 0; i < lg; i++) { cont = mul(cont, s); s = mul(2, mul(s, s)); } st.resize(2 * M); len.resize(2 * M); lazy.resize(2 * M); for (int i = 0; i < M; i++) { st[i + M] = A[i]; len[i + M] = 1; } for (int i = M - 1; i; i--) { st[i] = st[i * 2] + st[i * 2 + 1]; len[i] = len[i * 2] + len[i * 2 + 1]; } } } } int count_ways(int L, int R) { if (bintree) { update(1, 0, M, L - N, R - N + 1); return mul(st[1], cont); } for (int i = L; i <= R; i++) { A[i - N] ^= 1; } vector<int> tot(N + M, 1), on(N + M), off(N + M); vector dp(N, vector{1}); for (int i = N + M - 1; i >= 0; i--) { if (i >= N) { tot[i] = 1; if (A[i - N] == 0) { off[i] = 1; } else { on[i] = 1; } } else { int f = ch[i].size(); for (int j = 1; j <= f; j++) { on[i] = add(on[i], mul(dp[i][j], j)); } tot[i] = mul(tot[i], f); off[i] = sub(tot[i], on[i]); } if (i) { tot[P[i]] = mul(tot[P[i]], tot[i]); dp[P[i]].push_back(dp[P[i]].back() * on[i]); for (int j = dp[P[i]].size() - 2; j >= 0; j--) { dp[P[i]][j] = mul(off[i], dp[P[i]][j]); if (j) { dp[P[i]][j] = add(dp[P[i]][j], mul(dp[P[i]][j - 1], on[i])); } } } } return on[0]; }
#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...