Submission #1172937

#TimeUsernameProblemLanguageResultExecution timeMemory
1172937thelegendary08Digital Circuit (IOI22_circuit)C++17
100 / 100
440 ms68920 KiB
#include "circuit.h"
 //#include<stub.cpp>
#include<bits/stdc++.h>
#define int long long
#define vi vector<int>
#define vout(v) for(auto u : v)cout<<u<<' '; cout<<'\n';
#define pb push_back
#define FOR(i, k, n) for(int i = k; i<n; i++)
#define f0r(i,n) for(int i = 0;  i< n; i++)
#define mp make_pair
using namespace std;
vector<signed> par;
vector<signed> state;
vector<vi> adj;
int n,m;
const int mod = 1e9 + 2022;
const int mxn = 2e5 + 5;
vi dep(mxn);
vi cont(mxn);
vi chil(mxn);
int binexp(int a, int b){
	int ret = 1;
	f0r(i, 30){
		if(b & (1 << i)){
			ret *= a;
			ret %= mod;
		}
		a *= a;
		a %= mod;
	}
	return ret;
}
vi tl(mxn * 2);
vi tr(mxn * 2);
vi tree(mxn * 2);
vi totcont(mxn * 2);
vi prod(mxn);

void build(int v, int l, int r){
	tl[v] = l;
	tr[v] = r;
	if(l == r){
		tree[v] = state[l] * cont[l];
		totcont[v] = cont[l];
	}
	else{
		int mid = (l + r) / 2;
		build(v * 2, l, mid);
		build(v*2+1, mid+1, r);
		tree[v] = tree[v*2] + tree[v*2+1];
		tree[v] %= mod;
		totcont[v] = totcont[v*2] + totcont[v*2+1];
		totcont[v] %= mod;
	}
}
vi la(mxn * 2);
void pull(int v){
	tree[v] = tree[v*2] + tree[v*2+1];
	tree[v] %= mod;
}
void toggle(int v){
	la[v] = 1 - la[v];
	tree[v] = totcont[v] - tree[v];
	tree[v] %= mod;
	if(tree[v] < 0){
		tree[v] += mod;
	}
}
void push(int v){
	if(la[v]){
		toggle(v*2);
		toggle(v*2+1);
		la[v] = 0;
	}
	
}
void update(int v, int l, int r){
	// cout<<"UPDATE "<<v<<'\n';
	if(tl[v] > r || tr[v] < l){
		return;
	}
	if(tl[v] >= l && tr[v] <= r){
		// cout<<"INRANGW "<<v<<'\n';
		// cout<<tree[v]<<'\n';
		toggle(v);
		// cout<<tree[v]<<'\n';
	}
	else{
		push(v);
		update(v*2, l, r);
		update(v*2+1, l, r);
		pull(v);
	}
}
int dfs(int node, int from){
	int p = chil[node];
	for(auto u : adj[node]){
		if(u != from && u < n){
			p *= dfs(u, node);
			p %= mod;
		}
	}
	prod[node] = p;
	return p;
}
void compcont(int node, int from, int cur){
	if(node >= n){
		cont[node - n] = cur;
		return;
	}
	vi pref(chil[node]);
	vi suf(chil[node]);
	vi prods;
	for(auto u : adj[node]){
		if(u != from){
			prods.pb(prod[u]);
		}
	}
	// vout(prods);
	pref[0] = prods[0];
	FOR(i, 1, chil[node]){
		pref[i] = pref[i-1] * prods[i];
		pref[i] %= mod;
	}
	suf[chil[node] - 1] = prods.back();
	for(int i = chil[node] - 2; i>=0; i--){
		suf[i] = suf[i+1] * prods[i];
		suf[i] %= mod;
	}
	// vout(pref);
	// vout(suf);
	int cnt = 0;
	for(auto u : adj[node]){
		if(u != from){
			int cc = cur;
			if(cnt != 0){
				cc *= pref[cnt - 1];
				cc %= mod;
			}
			if(cnt != suf.size() - 1){
				cc *= suf[cnt + 1];
				cc %= mod;
			}
			// cout<<cc<<'\n';
			compcont(u, node, cc);
			cnt++;
		}
	}
}
void init(signed N, signed M, std::vector<signed> P, std::vector<signed> A) {
	n = N; m = M; par = P; state = A;
	adj.resize(n + m);
	FOR(i, 1, n+m){
		adj[P[i]].pb(i);
		chil[P[i]]++;
	}
	dfs(0, -1);
	for(int i = n; i<n+m; i++)prod[i] = 1;
	// f0r(i,n+m)cout<<prod[i]<<' ';
	  // cout<<'\n';
	 compcont(0, -1, 1);
	 // f0r(i,m)cout<<cont[i]<<' ';
	 // cout<<'\n';
	build(1, 0, m-1);
}

signed count_ways(signed l, signed r) {
	l -= n; r -= n;
	update(1, l, r);
	return tree[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...