Submission #837394

#TimeUsernameProblemLanguageResultExecution timeMemory
837394NothingXDDigital Circuit (IOI22_circuit)C++17
100 / 100
886 ms23880 KiB
#include "circuit.h"
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void debug_out(){cerr<<endl;}
template<typename Head, typename... Tail>
void debug_out(Head H, Tail... T){
	cerr << H << ' ';
	debug_out(T...);
}

const int mod = 1000002022;

#define debug(...) cerr << "(" << #__VA_ARGS__ << "): ", debug_out(__VA_ARGS__)
#define F first
#define S second
#define all(x) x.begin(), x.end()
#define MP(x, y) make_pair(x, y)
#define add(x, y) (x + y >= mod? x+y-mod: x+y)
#define sub(x, y) (x - y < 0? x-y+mod: x-y)

const int maxn = 1e5 + 10;

int n, m, p[maxn << 1], a[maxn], dp[maxn], val[maxn], cnt[maxn][2], phi = 1 * 222 * 2242156;
pii seg[maxn << 2];
bool lazy[maxn << 2];
vector<int> g[maxn];

int pw(int a, int b){
//	debug(a, b);
	int res = 1;
	for (; b; b >>= 1, a = 1ll * a * a % mod) if (b & 1) res = 1ll * res * a % mod;
//	debug(res);
	return res;
}

pair<int,pii> dfs(int v){
	if (v >= n){
		val[v] = 1;
		return {1, {0, 0}};
	}
	int x = g[v].size();
	while(x % 2 == 0){
		cnt[v][0]++;
		x /= 2;
	}
	while(x % 223 == 0){
		cnt[v][1]++;
		x /= 223;
	}
	val[v] = x;
	pair<int,pii> res = {val[v], {cnt[v][0], cnt[v][1]}};
	for (auto u: g[v]){
		pair<int,pii> tmp = dfs(u);
		res.F = 1ll * res.F * tmp.F % mod;
		res.S.F += tmp.S.F;
		res.S.S += tmp.S.S;
	}
	return res;
}

void solve(int v, pair<int,pii> tmp){
	//debug(v);
	if (v >= n){
		dp[v-n] = 1ll * tmp.F * pw(2, tmp.S.F) % mod * pw(223, tmp.S.S) % mod;
	//	debug(v, dp[v-n], tmp.F, tmp.S.F, tmp.S.S);
		return;
	}
	tmp.F = 1ll * tmp.F * pw(val[v], phi-1) % mod;
	tmp.S.F -= cnt[v][0];
	tmp.S.S -= cnt[v][1];
	for (auto u: g[v]){
		solve(u, tmp);
	}
}

pii operator +(pii a, pii b){
	return MP(add(a.F, b.F), add(a.S, b.S));
}

void shift(int v, int l, int r);

void build(int v, int l, int r){
	if (l + 1 == r){
		seg[v] = {dp[l], 0};
		if (a[l] == 0) swap(seg[v].F, seg[v].S);
		return;
	}
	int mid = (l + r) >> 1;
	build(v << 1, l, mid);
	build(v << 1 | 1, mid, r);
	seg[v] = seg[v << 1] + seg[v << 1 | 1];
}

void change(int v, int l, int r, int ql, int qr){
	if (qr <= l || r <= ql) return;
	if (ql <= l && r <= qr){
		swap(seg[v].F, seg[v].S);
		lazy[v] = !lazy[v];
		return;
	}
	shift(v, l, r);
	int mid = (l + r) >> 1;
	change(v << 1, l, mid, ql, qr);
	change(v << 1 | 1, mid, r, ql, qr);
	seg[v] = seg[v << 1] + seg[v << 1 | 1];
}

void shift(int v, int l, int r){
	if (!lazy[v]) return;
	int mid = (l + r) >> 1;
	change(v << 1, l, mid, l, mid);
	change(v << 1 | 1, mid, r, mid, r);
	lazy[v] = false;
}

void init(int N, int M, std::vector<int> P, std::vector<int> A) {
	n = N;
	m = M;
	for (int i = 1; i < n+m; i++){
		p[i] = P[i];
		g[p[i]].push_back(i);
	}
	for (int i = 0; i < m; i++) a[i] = A[i];
//	debug(1);
	pair<int,pii> tmp = dfs(0);
//	debug(tmp.F, tmp.S.F, tmp.S.S);
//	debug(2);
	solve(0, tmp);
//	debug(3);
	build(1, 0, m);
}

int count_ways(int L, int R) {
	L -= n;
	R -= n;
	change(1, 0, m, L, R+1);
	return seg[1].F;
}
#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...