Submission #1220186

#TimeUsernameProblemLanguageResultExecution timeMemory
1220186banganDigital Circuit (IOI22_circuit)C++20
100 / 100
391 ms36428 KiB
#include "circuit.h" // #include <vector> #include <bits/stdc++.h> using i64 = long long; constexpr int mod = 1'000'002'022; int n, m; std::vector<int> p, a; std::vector<std::vector<int>> inp; std::vector<int> sub; std::vector<int> cof; void calc_sub(int v) { if (v < n) { sub[v] = inp[v].size(); } else { sub[v] = 1; } for (int u : inp[v]) { calc_sub(u); sub[v] = 1ll * sub[v] * sub[u] % mod; } } void calc_cof(int v) { auto &t = inp[v]; int size = t.size(); std::vector<int> pre(size + 1); pre[0] = 1; for (int i = 1; i <= size; i++) { pre[i] = 1ll * pre[i - 1] * sub[t[i - 1]] % mod; } std::vector<int> suf(size + 1); suf[size] = 1; for (int i = size - 1; i >= 0; i--) { suf[i] = 1ll * suf[i + 1] * sub[t[i]] % mod; } for (int i = 0; i < size; i++) { int u = t[i]; cof[u] = 1ll * pre[i] * suf[i + 1] % mod * cof[v] % mod; calc_cof(u); } } std::vector<std::array<int, 2>> sum; std::vector<int> lazy; #define LC (2 * v) #define RC (2 * v + 1) #define mid ((l + r) / 2) void push(int v) { if (lazy[v] == 1) { std::swap(sum[v][0], sum[v][1]); } if (LC < 4 * m) { lazy[LC] ^= lazy[v]; } if (RC < 4 * m) { lazy[RC] ^= lazy[v]; } lazy[v] = 0; } void pull(int v) { push(v); push(LC); push(RC); sum[v][0] = (sum[LC][0] + sum[RC][0]) % mod; sum[v][1] = (sum[LC][1] + sum[RC][1]) % mod; } void add(int i, int t, int x, int v = 1, int l = 0, int r = m) { if (r - l == 1) { sum[v][t] = x; return; } if (i < mid) { add(i, t, x, LC, l, mid); } else { add(i, t, x, RC, mid, r); } pull(v); } void invert(int s, int e, int v = 1, int l = 0, int r = m) { push(v); if (s <= l && r <= e) { lazy[v] ^= 1; push(v); return; } if (s < mid) { invert(s, e, LC, l, mid); } if (e > mid) { invert(s, e, RC, mid, r); } pull(v); } void init(int N, int M, std::vector<int> P, std::vector<int> A) { n = N; m = M; p = P; a = A; inp.resize(n + m); for (int i = 1; i < n + m; i++) { inp[p[i]].push_back(i); } sub.resize(n + m); calc_sub(0); cof.resize(n + m); cof[0] = 1; calc_cof(0); // std::cerr << "cofs:\n"; // for (int i = 0; i < n + m; i++) { // std::cerr << "cof[" << i << "] = " << cof[i] << '\n'; // } sum.resize(4 * m); lazy.resize(4 * m); for (int i = 0; i < m; i++) { add(i, a[i], cof[i + n]); } } int count_ways(int L, int R) { invert(L - n, R - n + 1); return sum[1][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...