Submission #1031841

#TimeUsernameProblemLanguageResultExecution timeMemory
1031841NeroZeinDigital Circuit (IOI22_circuit)C++17
46 / 100
690 ms13788 KiB
#include "circuit.h" #include "bits/stdc++.h" using namespace std; const int MAX_N = 1e5 + 5; const int md = 1000002022; struct node { int tot_sum = 0, sum = 0; bool lazy = 0; }; int add(int x, int y) { x += y; if (x >= md) x -= md; return x; } int sub(int x, int y) { x -= y; if (x < 0) x += md; return x; } int mul(int x, int y) { return (int) ((long long) x * y % md); } int n, m; vector<int> a; int dp[MAX_N]; int contrib[MAX_N]; node seg[MAX_N * 2]; vector<int> g[MAX_N]; void dfs(int v) { if (v >= n) { dp[v] = 1; return; } dp[v] = g[v].size(); for (int u : g[v]) { dfs(u); dp[v] = mul(dp[v], dp[u]); } //cerr << "V, dp[V]: " << v << ' ' << dp[v] << '\n'; } void dfs2(int v, int val = 1) { //cerr << "V, Val: " << v << ' ' << val << '\n'; if (v >= n) { contrib[v - n] = val; return; } int sz = (int) g[v].size(); vector<int> pref(sz), suf(sz); pref[0] = suf[sz - 1] = 1; for (int i = 1; i < sz; ++i) { int u = g[v][i - 1]; pref[i] = mul(pref[i - 1], dp[u]); } for (int i = sz - 2; i >= 0; --i) { int u = g[v][i + 1]; suf[i] = mul(suf[i + 1], dp[u]); } for (int i = 0; i < sz; ++i) { int u = g[v][i]; int nval = mul(val, pref[i]); nval = mul(nval, suf[i]); dfs2(u, nval); } } node combine(node lx, node rx) { node ret; ret.sum = add(lx.sum, rx.sum); ret.tot_sum = add(lx.tot_sum, rx.tot_sum); return ret; } void build(int nd, int l, int r) { if (l == r) { seg[nd].tot_sum = contrib[l]; if (a[l]) { seg[nd].sum = contrib[l]; } return; } int mid = (l + r) >> 1; int rs = nd + ((mid - l + 1) << 1); build(nd + 1, l, mid); build(rs, mid + 1, r); seg[nd] = combine(seg[nd + 1], seg[rs]); } void push(int nd, int l, int r) { if (!seg[nd].lazy) { return; } seg[nd].sum = sub(seg[nd].tot_sum, seg[nd].sum); if (l != r) { int mid = (l + r) >> 1; int rs = nd + ((mid - l + 1) << 1); seg[nd + 1].lazy ^= 1; seg[rs].lazy ^= 1; } seg[nd].lazy = false; } void upd(int nd, int l, int r, int s, int e) { //cerr << "l, r, s, e: " << l << ' ' << r << ' ' << s << ' ' << e << '\n'; push(nd, l, r); if (l >= s && r <= e) { seg[nd].lazy = 1; push(nd, l, r); return; } int mid = (l + r) >> 1; int rs = nd + ((mid - l + 1) << 1); if (mid >= e) { push(rs, mid + 1, r); upd(nd + 1, l, mid, s, e); } else { if (mid < s) { push(nd + 1, l, mid); upd(rs, mid + 1, r, s, e); } else { upd(nd + 1, l, mid, s, e); upd(rs, mid + 1, r, s, e); } } seg[nd] = combine(seg[nd + 1], seg[rs]); return; } void init(int N, int M, std::vector<int> P, std::vector<int> A) { n = N; m = M; a = A; for (int i = 1; i < n + m; ++i) { g[P[i]].push_back(i); } dfs(0); dfs2(0); build(0, 0, m - 1); } int count_ways(int l, int r) { upd(0, 0, m - 1, l - n, r - n); return seg[0].sum; }
#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...