Submission #1128954

#TimeUsernameProblemLanguageResultExecution timeMemory
1128954vladiliusDigital Circuit (IOI22_circuit)C++20
61 / 100
3035 ms32896 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; using pii = pair<int, int>; #define pb push_back #define ff first #define ss second const int mod = 1000002022; vector<vector<int>> g, dp; vector<int> a; int n, m; bool ind; void fill(int v){ if (g[v].empty()) return; int k = (int) g[v].size(), pr = k; for (int i: g[v]){ fill(i); pr = (1LL * pr * (dp[i][0] + dp[i][1])) % mod; } vector<vector<int>> f(k + 1, vector<int>(k + 1)); f[0][0] = 1; for (int i = 1; i <= k; i++){ int u = g[v][i - 1]; f[i][0] = (1LL * f[i - 1][0] * dp[u][0]) % mod; for (int j = 1; j <= k; j++){ f[i][j] = (1LL * f[i - 1][j] * dp[u][0] + 1LL * f[i - 1][j - 1] * dp[u][1]) % mod; } } dp[v][1] = 0; for (int i = 1; i <= k; i++){ dp[v][1] = (dp[v][1] + 1LL * i * f[k][i]) % mod; } dp[v][0] = (pr - dp[v][1]) % mod; if (dp[v][0] < 0) dp[v][0] += mod; } vector<int> P; void dfs1(int v){ P[v] = (int) g[v].size(); if (!P[v]) P[v] = 1; for (int i: g[v]){ dfs1(i); P[v] = (1LL * P[v] * P[i]) % mod; } } vector<int> f; void dfs2(int v){ for (int i: g[v]){ int x = ((i == g[v][0]) ? P[g[v][1]] : P[g[v][0]]); f[i] = (1LL * f[v] * x) % mod; dfs2(i); } } struct node{ int s, X; }; vector<node> t; vector<bool> p; void build(int v, int tl, int tr){ if (tl == tr){ t[v].X = f[tl + n - 1]; t[v].s = a[tl - 1] * t[v].X; return; } int tm = (tl + tr) / 2, vv = 2 * v; build(vv, tl, tm); build(vv + 1, tm + 1, tr); t[v].s = (t[vv].s + t[vv + 1].s) % mod; t[v].X = (t[vv].X + t[vv + 1].X) % mod; } void push(int& v){ if (!p[v]) return; int vv = 2 * v; t[vv].s = (t[vv].X - t[vv].s) % mod; if (t[vv].s < 0) t[vv].s += mod; t[vv + 1].s = (t[vv + 1].X - t[vv + 1].s) % mod; if (t[vv + 1].s < 0) t[vv + 1].s += mod; p[vv] = !p[vv]; p[vv + 1] = !p[vv + 1]; p[v] = 0; } void upd(int v, int tl, int tr, int& l, int& r){ if (l > tr || r < tl) return; if (l <= tl && tr <= r){ t[v].s = (t[v].X - t[v].s) % mod; if (t[v].s < 0) t[v].s += mod; p[v] = !p[v]; return; } int tm = (tl + tr) / 2, vv = 2 * v; push(v); upd(vv, tl, tm, l, r); upd(vv + 1, tm + 1, tr, l, r); t[v].s = (t[vv].s + t[vv + 1].s) % mod; } void upd(int l, int r){ upd(1, 1, m, l, r); } int count_ways(int l, int r){ l -= n; r -= n; if (ind){ l++; r++; upd(l, r); return t[1].s; } else { for (int i = l; i <= r; i++){ a[i] = !a[i]; } for (int i = n; i < n + m; i++){ dp[i][1] = a[i - n]; dp[i][0] = !dp[i][1]; } fill(0); return dp[0][1]; } } void init(int N, int M, vector<int> pr, vector<int> A){ n = N; m = M; a = A; g.resize(n + m); for (int i = 1; i < n + m; i++){ g[pr[i]].pb(i); } ind = 1; for (int i = 0; i < n; i++){ if (g[i].size() != 2){ ind = 0; } } dp.resize(n + m); for (int i = 0; i < dp.size(); i++){ dp[i].resize(2); } if (ind){ P.resize(n + m); dfs1(0); f.resize(n + m); f[0] = 1; dfs2(0); t.resize(4 * m); p.resize(4 * m); build(1, 1, m); } }
#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...