Submission #1191802

#TimeUsernameProblemLanguageResultExecution timeMemory
1191802catch_me_if_you_canDigital Circuit (IOI22_circuit)C++20
4 / 100
291 ms15180 KiB
#include<bits/stdc++.h>
#include "circuit.h"
using namespace std;
#define fint signed
#define int long long
#define in array<int, 2>
#define pb push_back
#define pob pop_back


const int MX = 2e5+5;
const int mod = 1e9+2022;

int NS, MS;

struct segment_tree
{
	vector<int> tree; vector<int> sum; vector<bool> lazy;
	void build(const vector<fint> &val, const vector<fint> &st, int id, int l, int r)
	{
		int m = (l+r)/2;
		if(l == r)
		{
			sum[id] = val[m];
			tree[id] = (st[m] ? val[m] : 0ll);
			return;
		}
		build(val, st, 2*id, l, m);
		build(val, st, 2*id+1, m+1, r);
		tree[id] = (tree[2*id]+tree[2*id+1])%mod;
		sum[id] = (sum[2*id]+sum[2*id+1])%mod;
		return;
	}
	void push(int id)
	{
		if(!lazy[id])
			return;
		lazy[2*id] = lazy[2*id+1] = 1;
		tree[2*id] = (sum[2*id]-tree[2*id]+mod)%mod;
		tree[2*id+1] = (sum[2*id+1]-tree[2*id+1]+mod)%mod;
		lazy[id] = 0;
		return;
	}
	void init(const vector<fint> &val, const vector<fint> &st, int n)
	{
		tree.resize(4*n+5);
		sum.resize(4*n+5);
		lazy.assign(4*n+5, false);
		build(val, st, 1, 0, n-1);
		return;
	}
	void upd(int ql, int qr, int id, int l, int r)
	{
		//cout << "Called " << endl;
		if(qr < l || r < ql)
			return;
		if((ql <= l) && (r <= qr))
		{
			tree[id] = (sum[id]-tree[id]+mod)%mod;
			lazy[id] = lazy[id]^1;
			return;
		}
		push(id);
		int m = (l+r)/2;
		upd(ql, qr, 2*id, l, m);
		upd(ql, qr, 2*id+1, m+1, r);
		tree[id] = (tree[2*id]+tree[2*id+1])%mod;
		return;
	}
	int Q()
	{
		return tree[1];
	}
};

segment_tree work;

int oth[MX];
int prod[MX];

vector<fint> val;
vector<int> adj[MX];

void dfs(int u)
{
	prod[u] = max(1ll, (int)adj[u].size());
	vector<int> w;
	for(int v: adj[u])
	{
		dfs(v);
		w.pb(prod[v]);
		prod[u]*=prod[v]; prod[u]%=mod;
	}
	//cout << "Running u = " << u << endl;
	int n = w.size();
	if(w.empty())
		return;
	int pref[n];
	int suff[n];
	pref[0] = w[0];
	for(int i = 1; i < n; i++)
		pref[i] = (pref[i-1]*w[i])%mod;
	suff[n-1] = w[n-1];
	for(int i = n-2; i >= 0; i--)
		suff[i] = (suff[i+1]*w[i])%mod;
	int cnt = 0;
	for(int v: adj[u])
	{
		oth[v] = 1;
		if(cnt > 0)
			oth[v]*=pref[cnt-1];
		if(cnt < (n-1))
			oth[v]*=suff[cnt+1];
		oth[v]%=mod;
		cnt++;
	}
	return;
}

void dfs2(int u, int VL = 1)
{
	if(u >= NS)
	{
		//cout << "Called u = " << u << " and VL = " << VL << endl;
		val[u-NS] = VL;
	}
	for(int v: adj[u])
	{
		int VL_p = (VL*oth[v])%mod;
		dfs2(v, VL_p);
	}
	return;
}

void init(fint n, fint m, vector<fint> p, vector<fint> a)
{
	NS = n;
	MS = m;
	for(int i = 0; i < n+m; i++)
		adj[i].clear();
	for(int i = 1; i < n+m; i++)
		adj[p[i]].pb(i);
	val.resize(m);
	dfs(0); dfs2(0);
	/*cout << "r - ";
	for(int i = n; i < n+m; i++)
		cout << val[i-n] << " ";
	cout << "\n";*/
	//cout << "Hey " << endl;
	work.init(val, a, m);
	return;
}

fint count_ways(fint L, fint R)
{
	int l = L-NS;
	int r = R-NS;
	work.upd(l, r, 1, 0, MS-1);
	return (fint)work.Q();
}
#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...