Submission #705587

#TimeUsernameProblemLanguageResultExecution timeMemory
705587danikoynovDigital Circuit (IOI22_circuit)C++17
100 / 100
1393 ms48364 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, bool type) { 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]) { int i = c; if (type == false) i = 1; for (i; 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, false); } ll spec_val[maxn], depth[maxn]; void fix_state(int v) { if (v >= n) { return; } int c = children[v].size(); vector < ll > exp; for (int u : children[v]) { exp.push_back(dp[u][0]); } vector < ll > pref[2]; pref[0].resize(c); pref[1].resize(c); pref[0][0] = exp[0]; for (int i = 1; i < c; i ++) { pref[0][i] = (pref[0][i - 1] * exp[i]) % mod; } pref[1][c - 1] = exp[c - 1]; for (int i = c - 2; i >= 0; i --) { pref[1][i] = (pref[1][i + 1] * exp[i]) % mod; } for (int i = 0; i < children[v].size(); i ++) { int u = children[v][i]; ll cur = 1; if (i > 0) cur = (cur * pref[0][i - 1]) % mod; if (i + 1 < c) { cur = (cur * pref[1][i + 1]) % mod; } ///cout << v << " : " << i << " : " << u << " " << cur << endl; depth[u] = (depth[v] * cur) % mod; } for (int u : children[v]) fix_state(u); } ll pw[maxn], pref[maxn]; ll con[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] = (con[left] * a[left]) % mod; 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]) % mod; } ll get_sum(int left, int right) { ll sum = pref[right]; if (left != 0) sum = sum - pref[left - 1]; if (sum < 0) sum += mod; return sum; } void push_lazy(int root, int left, int right) { if (lazy[root] == 0) return; tree[root] = (get_sum(left, right) - tree[root] + mod) % mod; 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); ///cout << left << " :: " << right << " :: " << tree[root] << endl; return; } int mid = (left + right) / 2; update_range(root * 2, left, mid, qleft, qright); update_range(root * 2 + 1, mid + 1, right, qleft, qright); ///cout << root << " " << left << " " << right << " " << qleft << " " << qright << endl; tree[root] = (tree[root * 2] + tree[root * 2 + 1]) % mod; ///cout << tree[root] << endl; } ll power(ll base, ll st) { ll ans = 1; while(st > 0) { if (st % 2 == 1) ans = (ans * base) % mod; base = (base * base) % mod; st /= 2; } return ans; } void init(int N, int M, std::vector<int> P, std::vector<int> A) { n = N; m = M; for (int i = 0; i < N + M; i ++) p[i] = P[i]; for (int i = 1; i < N + M; i ++) { children[p[i]].push_back(i); } depth[0] = 1; solve_state(0); fix_state(0); for (int i = 0; i < M; i ++) con[i] = depth[i + n]; /**for (int i = 0; i < M; i ++) { a[i] = 1; int v = i + n; while(v != -1) { update_state(v, false); v = p[v]; } ///solve_state(0); con[i] = dp[0][1]; a[i] = 0; v = i + n; while(v != -1) { update_state(v, false); v = p[v]; } }*/ pref[0] = con[0]; for (int i = 1; i < M; i ++) pref[i] = (pref[i - 1] + con[i]) % mod; for (int i = 0; i < M; i ++) a[i] = A[i]; build_tree(1, 0, m - 1); } int count_ways(int L, int R) { update_range(1, 0, m - 1, L - n, R - n); ///for (int i = L - n; i <= R - n; i ++) /// a[i] = ((a[i] + 1) & 1); /**ll ans = 0; for (int i = 0; i < m; i ++) { ans = (ans + (con[i] * a[i])) % mod; }*/ /**cout << "-----------" << endl; for (int i = 0; i < n + m; i ++) cout << i << " : " << dp[i][0] << " " << dp[i][1] << endl;*/ return tree[1]; }

Compilation message (stderr)

circuit.cpp: In function 'void update_state(int, bool)':
circuit.cpp:37:14: warning: statement has no effect [-Wunused-value]
   37 |         for (i; i >= 0; i --)
      |              ^
circuit.cpp: In function 'void fix_state(int)':
circuit.cpp:102:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  102 |     for (int i = 0; i < children[v].size(); i ++)
      |                     ~~^~~~~~~~~~~~~~~~~~~~
#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...