Submission #705510

#TimeUsernameProblemLanguageResultExecution timeMemory
705510danikoynovDigital Circuit (IOI22_circuit)C++17
34 / 100
1010 ms16380 KiB
#include "circuit.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; const ll mod = 1000002022; const int maxn = 2e5 + 10; int n, m, p[maxn], a[maxn]; vector < int > children[maxn]; ll dp[maxn][2], temp[maxn]; void update_state(int v) { dp[v][0] = dp[v][1] = 0; if (v >= n) { dp[v][1] = a[v - n]; dp[v][0] = 1 - dp[v][1]; return; } int c = children[v].size(); for (int i = 0; i <= c; i ++) temp[i] = 0; temp[0] = 1; for (int u : children[v]) { for (int i = c; i >= 0; i --) { temp[i] = (temp[i] * dp[u][0]) % mod; if (i > 0) temp[i] = (temp[i] + temp[i - 1] * dp[u][1]) % mod; } } for (int i = 0; i <= c; i ++) { dp[v][0] = (dp[v][0] + temp[i] * (ll)(c - i)) % mod; dp[v][1] = (dp[v][1] + temp[i] * (ll)(i)) % mod; } ///cout << v << " " << dp[v][0] << " " << dp[v][1] << endl; } void solve_state(int v) { for (int u : children[v]) { solve_state(u); } update_state(v); } ll pw[maxn]; int act = 0, logM = 0; int tree[4 * maxn], lazy[4 * maxn]; void build_tree(int root, int left, int right) { if (left == right) { tree[root] = a[left]; return; } int mid = (left + right) / 2; build_tree(root * 2, left, mid); build_tree(root * 2 + 1, mid + 1, right); tree[root] = tree[root * 2] + tree[root * 2 + 1]; } void push_lazy(int root, int left, int right) { if (lazy[root] == 0) return; tree[root] = (right - left + 1) - tree[root]; if (left != right) { lazy[root * 2] = (lazy[root * 2] + 1) % 2; lazy[root * 2 + 1] = (lazy[root * 2 + 1] + 1) % 2; } lazy[root] = 0; } void update_range(int root, int left, int right, int qleft, int qright) { push_lazy(root, left, right); if (left > qright || right < qleft) return; if (left >= qleft && right <= qright) { lazy[root] = 1; push_lazy(root, left, right); return; } int mid = (left + right) / 2; update_range(root * 2, left, mid, qleft, qright); update_range(root * 2 + 1, mid + 1, right, qleft, qright); tree[root] = tree[root * 2] + tree[root * 2 + 1]; } void init(int N, int M, std::vector<int> P, std::vector<int> A) { n = N; m = M; pw[0] = 1; for (int i = 1; i <= M; i ++) pw[i] = (pw[i - 1] * (ll)(2)) % mod; while((1 << logM) < M) logM ++; for (int i = 0; i < N + M; i ++) p[i] = P[i]; for (int i = 0; i < M; i ++) a[i] = A[i], act += a[i]; for (int i = 1; i < N + M; i ++) { children[p[i]].push_back(i); } solve_state(0); build_tree(1, 0, M - 1); } int count_ways(int L, int R) { if (n > 1000 || m > 1000) { update_range(1, 0, m - 1, L - n, R - n); ll ans = (pw[n - logM] * tree[1]) % mod; return ans; } else { for (int i = L - n; i <= R - n; i ++) a[i] = ((a[i] + 1) & 1); solve_state(0); } return dp[0][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...