Submission #217792

#TimeUsernameProblemLanguageResultExecution timeMemory
217792MarcoMeijerWerewolf (IOI18_werewolf)C++14
100 / 100
812 ms129800 KiB
#include "werewolf.h"
#include <bits/stdc++.h>
using namespace std;

//macros
typedef long long ll;
typedef pair<int, int> ii;
typedef tuple<int, int, int> iii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<iii> viii;
typedef vector<ll> vll;
#define REP(a,b,c) for(int a=int(b); a<int(c); a++)
#define RE(a,c) REP(a,0,c)
#define RE1(a,c) REP(a,1,c+1)
#define REI(a,b,c) REP(a,b,c+1)
#define REV(a,b,c) for(int a=int(c-1); a>=int(b); a--)
#define INF 1e9
#define pb push_back
#define fi first
#define se second
#define sz size()
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int MX=5e5;

class RootedTree {
public:
	RootedTree() {
		RE(i,MX) p[i] = -1;
	}
	void addChild(int parent, int child) {
		chl[parent].pb(child);
		p[child] = parent;
	}
	void createA(int u) {
		a[m] = u;
		bg[u] = m++;
		for(int v:chl[u]) createA(v);
		ed[u] = m-1;
	}
	void createA() {
		createA(root);
	}

	vi chl[MX];
	int p[MX];
	int root;
	int a[MX], bg[MX], ed[MX];
	int m=0;
};

int m, q, n;
vi adj[MX];
vi atL[MX], atR[MX];
vi A, X, Y, S, E, L, R;
int p[MX], r[MX];
RootedTree treeH, treeW;
int SEG[MX*4];
int SA[MX];

int getSet(int i) {return i==p[i]?i:p[i]=getSet(p[i]);}
bool isSameSet(int i, int j) {return getSet(i)==getSet(j);}
void unionSet(int i, int j) {
	if(!isSameSet(i,j)) {
		i=getSet(i), j=getSet(j);
		p[j] = i;
	}
}

void setSeg(int i, int x, int p=0, int l=0, int r=n-1) {
	if(i < l || i > r) return;
	if(l == r) {
		SEG[p] = x;
		return;
	}
	int m=(l+r)/2;
	setSeg(i,x,p*2+1,l,m);
	setSeg(i,x,p*2+2,m+1,r);
	SEG[p] = max(SEG[p*2+1], SEG[p*2+2]);
}
int getSeg(int i, int j, int p=0, int l=0, int r=n-1) {
	if(j < l || i > r) return -1;
	if(i <= l && j >= r) return SEG[p];
	int m=(l+r)/2;
	int a=getSeg(i,j,p*2+1,l,m);
	int b=getSeg(i,j,p*2+2,m+1,r);
	return max(a,b);
}

vi check_validity(int N, vi _X, vi _Y, vi _S, vi _E, vi _L, vi _R) {
	n = N;
	m = _X.size();
	q = _S.size();
	L=_L, R=_R, X=_X, Y=_Y, S=_S, E=_E;
	A.assign(q, 0);
	RE(i,m) {
		adj[X[i]].pb(Y[i]);
		adj[Y[i]].pb(X[i]);
	}

	RE(i,q) {
		atL[L[i]].pb(i);
		atR[R[i]].pb(i);
	}

	RE(i,n) p[i]=i, r[i]=0;
	RE(i,n) {
		for(int j:adj[i]) {
			if(j > i || isSameSet(i,j)) continue;
			j = getSet(j);
			unionSet(i,j);
			treeW.addChild(i,j);
		}
		for(int j:atR[i]) E[j] = getSet(E[j]);
	}
	treeW.root = n-1;
	RE(i,n) p[i]=i, r[i]=0;
	REV(i,0,n) {
		for(int j:adj[i]) {
			if(j < i ||isSameSet(i,j)) continue;
			j = getSet(j);
			unionSet(i,j);
			treeH.addChild(i,j);
		}
		for(int j:atL[i]) S[j] = getSet(S[j]);
	}
	treeH.root = 0;
	treeW.createA();
	treeH.createA();

	viii queries;
	RE(curQ,q) {
		int bg, ed;
		int u = S[curQ];
		bg = treeH.bg[u];
		ed = treeH.ed[u];
		queries.pb(tie(ed,bg,curQ));
	}
	sort(queries.begin(), queries.end());
	RE(i,n*4) SEG[i] = -1;
	RE(i,n) SA[treeW.a[i]] = i;

	int j=0;
	for(iii p : queries) {
		int bg, ed, curQ;
		tie(ed, bg, curQ) = p;
		while(j <= ed) {
			setSeg(SA[treeH.a[j]],j);
			j++;
		}
		int u = E[curQ];
		if(getSeg(treeW.bg[u], treeW.ed[u]) >= bg) {
			A[curQ] = 1;
		} else {
			A[curQ] = 0;
		}
	}

	return A;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...