This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
// 人外有人,天外有天
// author: Ausp3x
#pragma GCC optimize("O1, O2, O3, Ofast, unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define fi first
#define se second
#define pb push_back
// #define DEBUG
#ifndef DEBUG
#include "circuit.h"
#endif
typedef long long lng;
typedef __int128 lll;
template<class T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
int const INF32 = 0x3f3f3f3f;
lng const INF64 = 0x3f3f3f3f3f3f3f3f;
lng N, M;
vector<int> P;
vector<lng> A;
vector<vector<int>> adjl;
struct ModInt {
lng const MOD = 1'000'002'022;
lng const PHI_MOD = 497'758'632;
lng exp_2 = 0, exp_223 = 0, rem = 0;
void init(lng x) {
while (x % 2 == 0 && x > 0) {
exp_2++;
x /= 2;
}
while (x % 223 == 0 && x > 0) {
exp_223++;
x /= 223;
}
rem = x % MOD;
}
void copy(ModInt const &x) {
exp_2 = x.exp_2;
exp_223 = x.exp_223;
rem = x.rem;
}
// only works when divisible by x
void divideBy(ModInt const &x) {
assert(exp_2 >= x.exp_2);
assert(exp_223 >= x.exp_223);
exp_2 -= x.exp_2;
exp_223 -= x.exp_223;
rem *= modPow(x.rem, PHI_MOD - 1, MOD);
rem %= MOD;
return;
}
lng getValue() {
return modPow(2, exp_2, MOD) * modPow(223, exp_223, MOD) % MOD * rem % MOD;
}
lng modPow(lng x, lng y, lng mod) {
lng res = 1;
while (y > 0) {
if (y & 1) {
res *= x;
res %= mod;
}
y >>= 1;
x *= x;
x %= mod;
}
return (res + mod) % mod;
}
};
struct SegTree {
lng const MOD = 1'000'002'022;
int l, r;
lng ttl = 0; // must be constant after initialization
lng sum = 0, upd = 0;
SegTree *l_child, *r_child;
template<class T>
SegTree(int l, int r, const vector<T> &arr): l(l), r(r) {
if (l == r) {
ttl = arr[l];
sum = arr[l];
l_child = r_child = nullptr;
} else {
int m = (l + r) / 2;
l_child = new SegTree(l, m, arr);
r_child = new SegTree(m + 1, r, arr);
ttl = (l_child->ttl + r_child->ttl) % MOD;
sum = (l_child->sum + r_child->sum) % MOD;
}
}
// push updates down to children
void push() {
if (l_child != nullptr && r_child != nullptr) {
l_child->upd += upd;
l_child->upd %= 2;
if (upd)
l_child->reverseSum();
r_child->upd += upd;
r_child->upd %= 2;
if (upd)
r_child->reverseSum();
upd = 0;
}
return;
}
// pull states up from children
void pull() {
assert(upd == 0);
if (l_child != nullptr && r_child != nullptr) {
sum = (l_child->sum + r_child->sum) % MOD;
}
return;
}
void rangeSumUpdate(int cur_l, int cur_r) {
if (cur_l > cur_r || (r < cur_l || cur_r < l)) {
return;
}
if (cur_l <= l && r <= cur_r) {
upd++;
upd %= 2;
reverseSum();
return;
}
push();
l_child->rangeSumUpdate(cur_l, cur_r);
r_child->rangeSumUpdate(cur_l, cur_r);
pull();
return;
}
lng rangeSumQuery(int cur_l, int cur_r) {
if (cur_l > cur_r || (r < cur_l || cur_r < l)) {
return 0;
}
if (cur_l <= l && r <= cur_r) {
return sum;
}
push();
return (l_child->rangeSumQuery(cur_l, cur_r) + r_child->rangeSumQuery(cur_l, cur_r)) % MOD;
}
void reverseSum() {
sum = (ttl - sum + MOD) % MOD;
}
void debugPrint(int depth = 0) {
for (int t = 0; t < depth; t++) {
cout << '\t';
}
cout << "[" << l << ", " << r << "] has ttl " << ttl << ", has sum " << sum << ", and upd " << upd << endl;
if (l_child != nullptr && r_child != nullptr) {
l_child->debugPrint(depth + 1);
r_child->debugPrint(depth + 1);
}
return;
}
};
vector<lng> W;
void initW(int cur, int prv) {
if (cur >= N)
return;
W[cur] = adjl[cur].size() - (cur != 0);
for (int nxt : adjl[cur]) {
if (nxt == prv)
continue;
initW(nxt, cur);
W[cur] *= W[nxt];
W[cur] %= 1'000'002'022;
}
return;
}
vector<ModInt> C;
void initC(int cur, int prv) {
ModInt cnt;
cnt.init(adjl[cur].size() - (cur != 0));
for (int nxt : adjl[cur]) {
if (nxt == prv)
continue;
C[nxt].copy(C[cur]);
C[nxt].divideBy(cnt);
initC(nxt, cur);
}
return;
}
SegTree *segt = nullptr;
void init(int _N, int _M, vector<int> _P, vector<int> _A) {
N = _N;
M = _M;
P.clear();
P.resize(N + M);
for (int i = 0; i < N + M; i++)
P[i] = _P[i];
A.clear();
A.resize(M);
for (int i = 0; i < M; i++)
A[i] = _A[i];
adjl.clear();
adjl.resize(N + M);
for (int i = 1; i < N + M; i++) {
adjl[P[i]].pb(i);
adjl[i].pb(P[i]);
}
W.clear();
W.resize(N + M, 1);
initW(0, 0);
C.clear();
C.resize(N + M);
C[0].init(W[0]);
initC(0, 0);
vector<lng> C_ints(M);
for (int i = 0; i < M; i++)
C_ints[i] = C[i + N].getValue();
segt = new SegTree(0, M - 1, C_ints);
for (int i = 0; i < M; i++)
if (!A[i])
segt->rangeSumUpdate(i, i);
// segt->debugPrint();
return;
}
int count_ways(int L, int R) {
L -= N;
R -= N;
segt->rangeSumUpdate(L, R);
// segt->debugPrint();
return segt->rangeSumQuery(0, M - 1);
}
#ifdef DEBUG
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t = 1;
// cin >> t;
while (t--) {
int _N, _M, Q;
cin >> _N >> _M >> Q;
vector<int> _P(_N + _M);
for (int &p : _P)
cin >> p;
vector<int> _A(_M);
for (int &a : _A)
cin >> a;
init(_N, _M, _P, _A);
while (Q--) {
int L, R;
cin >> L >> R;
cout << count_ways(L, R) << endl;
}
}
return 0;
}
#endif
Compilation message (stderr)
circuit.cpp:4:55: warning: bad option '-f O2' to pragma 'optimize' [-Wpragmas]
4 | #pragma GCC optimize("O1, O2, O3, Ofast, unroll-loops")
| ^
circuit.cpp:4:55: warning: bad option '-f O3' to pragma 'optimize' [-Wpragmas]
circuit.cpp:4:55: warning: bad option '-f Ofast' to pragma 'optimize' [-Wpragmas]
circuit.cpp:4:55: warning: bad option '-f unroll-loops' to pragma 'optimize' [-Wpragmas]
In file included from circuit.cpp:15:
circuit.h:3:63: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
3 | void init(int N, int M, std::vector<int> P, std::vector<int> A);
| ^
circuit.h:3:63: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.h:3:63: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.h:3:63: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.h:3:63: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
circuit.h:3:63: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.h:3:63: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.h:3:63: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.h:4:28: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
4 | int count_ways(int L, int R);
| ^
circuit.h:4:28: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.h:4:28: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.h:4:28: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.h:4:28: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
circuit.h:4:28: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.h:4:28: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.h:4:28: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.cpp:35:20: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
35 | void init(lng x) {
| ^
circuit.cpp:35:20: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.cpp:35:20: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.cpp:35:20: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.cpp:49:30: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
49 | void copy(ModInt const &x) {
| ^
circuit.cpp:49:30: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.cpp:49:30: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.cpp:49:30: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.cpp:56:34: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
56 | void divideBy(ModInt const &x) {
| ^
circuit.cpp:56:34: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.cpp:56:34: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.cpp:56:34: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.cpp:68:18: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
68 | lng getValue() {
| ^
circuit.cpp:68:18: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.cpp:68:18: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.cpp:68:18: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.cpp:72:37: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
72 | lng modPow(lng x, lng y, lng mod) {
| ^
circuit.cpp:72:37: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.cpp:72:37: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.cpp:72:37: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.cpp:97:47: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
97 | SegTree(int l, int r, const vector<T> &arr): l(l), r(r) {
| ^
circuit.cpp:97:47: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.cpp:97:47: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.cpp:97:47: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.cpp:112:15: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
112 | void push() {
| ^
circuit.cpp:112:15: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.cpp:112:15: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.cpp:112:15: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.cpp:129:15: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
129 | void pull() {
| ^
circuit.cpp:129:15: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.cpp:129:15: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.cpp:129:15: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.cpp:138:45: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
138 | void rangeSumUpdate(int cur_l, int cur_r) {
| ^
circuit.cpp:138:45: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.cpp:138:45: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.cpp:138:45: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.cpp:157:43: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
157 | lng rangeSumQuery(int cur_l, int cur_r) {
| ^
circuit.cpp:157:43: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.cpp:157:43: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.cpp:157:43: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.cpp:170:21: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
170 | void reverseSum() {
| ^
circuit.cpp:170:21: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.cpp:170:21: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.cpp:170:21: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.cpp:174:34: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
174 | void debugPrint(int depth = 0) {
| ^
circuit.cpp:174:34: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.cpp:174:34: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.cpp:174:34: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.cpp:189:28: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
189 | void initW(int cur, int prv) {
| ^
circuit.cpp:189:28: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.cpp:189:28: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.cpp:189:28: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.cpp:208:28: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
208 | void initC(int cur, int prv) {
| ^
circuit.cpp:208:28: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.cpp:208:28: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.cpp:208:28: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.cpp:226:57: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
226 | void init(int _N, int _M, vector<int> _P, vector<int> _A) {
| ^
circuit.cpp:226:57: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.cpp:226:57: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.cpp:226:57: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
circuit.cpp:268:28: warning: bad option '-f O2' to attribute 'optimize' [-Wattributes]
268 | int count_ways(int L, int R) {
| ^
circuit.cpp:268:28: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
circuit.cpp:268:28: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
circuit.cpp:268:28: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |