제출 #976669

#제출 시각아이디문제언어결과실행 시간메모리
976669happypotato디지털 회로 (IOI22_circuit)C++17
100 / 100
734 ms42176 KiB
#include "circuit.h"
#include <vector>
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define ff first
#define ss second
#define pb push_back
const ll MOD = 1e9 + 2022;
const int mxN = 1e5 + 10;
vector<int> adj[2 * mxN];
int n, m;
bool state[2 * mxN];
ll contrib[2 * mxN];
void dfs1(int u = 0) {
	if (u >= n) {
		contrib[u] = 1; return;
	}
	contrib[u] = adj[u].size();
	for (int v : adj[u]) {
		dfs1(v);
		contrib[u] = (contrib[u] * contrib[v]) % MOD;
	}
}
void dfs2(int u = 0, ll pass = 1) {
	if (u >= n) {
		contrib[u] = pass; return;
	}
	int sz = adj[u].size();
	vector<ll> pref(sz + 2), suff(sz + 2);
	pref[0] = 1;
	for (int i = 1; i <= sz; i++) {
		pref[i] = (pref[i - 1] * contrib[adj[u][i - 1]]) % MOD;
	}
	suff[sz + 1] = 1;
	for (int i = sz; i >= 1; i--) {
		suff[i] = (suff[i + 1] * contrib[adj[u][i - 1]]) % MOD;
	}
	for (int i = 1; i <= sz; i++) {
		ll nxt = pass;
		nxt = (nxt * pref[i - 1]) % MOD;
		nxt = (nxt * suff[i + 1]) % MOD;
		dfs2(adj[u][i - 1], nxt);
	}
}
ll seg[4 * mxN], tot[4 * mxN];
bool lazy[4 * mxN];
void pushdown(int idx) {
	if (!lazy[idx]) return;
	seg[(idx << 1)] = (tot[(idx << 1)] - seg[(idx << 1)] + MOD) % MOD;
	seg[(idx << 1) | 1] = (tot[(idx << 1) | 1] - seg[(idx << 1) | 1] + MOD) % MOD;
	lazy[(idx << 1)] ^= 1; lazy[(idx << 1) | 1] ^= 1;
	lazy[idx] = false;
}
void build(int l = n, int r = n + m - 1, int idx = 1) {
	if (l == r) {
		seg[idx] = (state[l] ? contrib[l] : 0LL);
		tot[idx] = contrib[l];
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, (idx << 1));
	build(mid + 1, r, (idx << 1) | 1);
	seg[idx] = (seg[(idx << 1)] + seg[(idx << 1) | 1]) % MOD;
	tot[idx] = (tot[(idx << 1)] + tot[(idx << 1) | 1]) % MOD;
}
void update(int tl, int tr, int l = n, int r = n + m - 1, int idx = 1) {
	if (tl <= l && r <= tr) {
		seg[idx] = (tot[idx] - seg[idx] + MOD) % MOD;
		lazy[idx] ^= 1;
		return;
	}
	pushdown(idx);
	int mid = (l + r) >> 1;
	if (tl <= mid) update(tl, tr, l, mid, (idx << 1));
	if (tr > mid) update(tl, tr, mid + 1, r, (idx << 1) | 1);
	seg[idx] = (seg[(idx << 1)] + seg[(idx << 1) | 1]) % MOD;
}
ll query() {
	return seg[1];
}
void init(int N, int M, vector<int> P, vector<int> A) {
	n = N; m = M;
	for (int i = 1; i < (int)(P.size()); i++) adj[P[i]].pb(i);
	for (int i = 0; i < (int)(A.size()); i++) state[n + i] = A[i];

	dfs1(); dfs2();
	build();
}
int count_ways(int L, int R) {
	update(L, R);
	return (int)(query());
}
/*
Observations:
Consider a particular source gate
Consider the set of solutions that toggles as the source gate toggles
(i.e. becomes valid/invalid as the source gate becomes on/off)
Then it can be shown that it is independent from other values
*/
#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...