제출 #1079136

#제출 시각아이디문제언어결과실행 시간메모리
1079136Boas디지털 회로 (IOI22_circuit)C++17
62 / 100
3052 ms64488 KiB
#include "circuit.h" #pragma GCC optimize("trapv") #include <bits/stdc++.h> using namespace std; #define int long long #define pb push_back #define loop(x, i) for (int i = 0; i < x; i++) #define rev(x, i) for (int i = (int)x - 1; i >= 0; i--) #define ALL(x) begin(x), end(x) #define sz(x) (int)x.size() typedef signed i32; typedef array<int, 2> ii; typedef vector<ii> vii; typedef vector<vii> vvii; typedef vector<bool> vb; typedef vector<int> vi; typedef vector<i32> vi32; typedef vector<vi> vvi; typedef vector<vvi> vvvi; constexpr int MOD = 1'000'002'022; vvi children; vi term01; int n, m, treeN = 1; struct val { int v = 0, totalV = 0; void swap() { v = (totalV - v + MOD) % MOD; } val operator+(const val &b) { val a = *this, res; res.v = a.v + b.v; res.totalV = a.totalV + b.totalV; res.totalV %= MOD; res.v %= MOD; return res; } }; vector<val> tree; vb lazy; void pull(int i) { tree[i] = tree[2 * i] + tree[2 * i + 1]; } void push(int i) { if (!lazy[i]) return; tree[i].swap(); if (i < treeN) { lazy[2 * i].flip(); lazy[2 * i + 1].flip(); } lazy[i] = 0; } val operation(int i, int l, int r, int ql, int qr, int op) { push(i); if (r < ql || qr < l) return {}; if (ql <= l && r <= qr) { if (op == 1) { lazy[i] = 1; push(i); } return tree[i]; } int mid = (l + r) / 2; val res = operation(2 * i, l, mid, ql, qr, op) + operation(2 * i + 1, mid + 1, r, ql, qr, op); pull(i); return res; }; int calc01s(int i) { if (i >= n) { return term01[i] = 1; } int all = sz(children[i]); for (int j : children[i]) { int v = calc01s(j); all *= v; all %= MOD; } return term01[i] = all; } vii calc(int i) { if (i >= n) { return {{i, 1}}; } int c = sz(children[i]); vi ones; vi prod, prefProd(c + 1, 1), sufProd(c + 1, 1); vvii vs; for (int j : children[i]) { vii cur = calc(j); vs.pb(cur); prod.pb(term01[j]); } loop(c, j) { prefProd[j + 1] = prefProd[j] * prod[j]; prefProd[j + 1] %= MOD; } rev(c, j) { sufProd[j] = sufProd[j + 1] * prod[j]; sufProd[j] %= MOD; } vii res; loop(c, j) { vii cur = vs[j]; int mult = (prefProd[j] * sufProd[j + 1]) % MOD; for (auto [ix, v] : cur) { res.pb({ix, (v * mult) % MOD}); } } return res; } void init(i32 N, i32 M, vi32 P, vi32 A) { n = N; m = M; while (treeN < m) treeN *= 2; tree.resize(2 * treeN); lazy.resize(2 * treeN); children = vvi(N); term01 = vi(N + M); loop(sz(P), i) { if (i == 0) continue; children[P[i]].pb(i); } calc01s(0); vii terms = calc(0); for (auto [i, v] : terms) { tree[treeN + (i - n)].totalV = v; if (A[i - n]) tree[treeN + (i - n)].v = v; } rev(treeN, i) pull(i); } i32 count_ways(i32 L, i32 R) { operation(1, 0, treeN - 1, L - n, R - n, 1); return (i32)operation(1, 0, treeN - 1, 0, m - 1, 0).v; }
#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...