Submission #771213

#TimeUsernameProblemLanguageResultExecution timeMemory
771213khshgWerewolf (IOI18_werewolf)C++14
100 / 100
452 ms86360 KiB
#include "werewolf.h"
#include<bits/stdc++.h>
using namespace std;

int N;
vector<vector<int>> adj;
vector<int> D;
vector<pair<int, int>> ch;

void init(int N) {
	D = vector<int>(N); iota(begin(D), end(D), 0);
	ch.resize(N);
}

int parent(int x) {
	return (D[x] == x ? x : D[x] = parent(D[x]));
}

void unite(int x, int y) {
	x = parent(x); y = parent(y);
	if(x == y) return;
	int s = (int)D.size();
	D[x] = D[y] = s;
	D.push_back(s);
	ch.emplace_back(x, y);
}

void dfs(int S, int& tim3) {
	if(S < N) {
		ch[S] = {tim3, tim3};
		++tim3;
		return;
	}
	int x, y;
	tie(x, y) = ch[S];
	dfs(x, tim3); dfs(y, tim3);
	ch[S].first = min(ch[x].first, ch[y].first);
	ch[S].second = max(ch[x].second, ch[y].second);
}

void merg3(vector<int>& es, const vector<int>& a, const vector<int>& b) {
	es.resize((int)a.size() + (int)b.size());
	int i = 0, j = 0;
	while(true) {
		if(i < (int)a.size() && j < (int)b.size()) {
			if(a[i] < b[j]) {
				es[i + j] = a[i];
				++i;
			} else {
				es[i + j] = b[j];
				++j;
			}
		} else if(i < (int)a.size()) {
			es[i + j] = a[i];
			++i;
		} else if(j < (int)b.size()) {
			es[i + j] = b[j];
			++j;
		} else break;
	}
}

vector<vector<int>> st;
int base;

void build(vector<pair<int, int>>& pos) {
	sort(begin(pos), end(pos));
	base = 1;
	while(base < N) {
		base *= 2;
	}
	st.resize(base * 2);
	for(int i = 0; i < N; ++i) {
		st[i + base].push_back(pos[i].second);
	}
	for(int i = base - 1; i >= 1; --i) {
		merg3(st[i], st[2 * i], st[2 * i + 1]);
	}
}

bool chck(int s, int l, int r) {
	auto it = lower_bound(begin(st[s]), end(st[s]), l);
	return (it != end(st[s]) && (*it) <= r);
}

bool query(int xl, int xr, int yl, int yr) {
	xl += base;
	xr += base;
	while(xl <= xr) {
		if(xl & 1) {
			if(chck(xl, yl, yr)) return 1;
			++xl;
		}
		if(!(xr & 1)) {
			if(chck(xr, yl, yr)) return 1;
			--xr;
		}
		xl /= 2;
		xr /= 2;
	}
	return 0;
}
 
vector<int> check_validity(int _N, vector<int> X, vector<int> Y, vector<int> S, vector<int> E, vector<int> L, vector<int> R) {
	N = _N;
	adj.resize(N);
	int M = (int)X.size();
	for(int i = 0; i < M; ++i) {
		adj[X[i]].push_back(Y[i]);
		adj[Y[i]].push_back(X[i]);
	}
	int Q = (int)L.size();
	vector<pair<int, int>> RL(Q), RR(Q), pos(N);
	{
		vector<int> sind(Q);
		iota(begin(sind), end(sind), 0);
		sort(begin(sind), end(sind), [&](const int& i, const int& j) { return L[i] > L[j]; });
		init(N);
		vector<int> par(Q);
		int i = N - 1;
		for(int j = 0; j < Q; ++j) {
			for(; i >= L[sind[j]]; --i) {
				for(auto& u : adj[i]) {
					if(u >= i) unite(u, i);
				}
			}
			par[sind[j]] = parent(S[sind[j]]);
		}
		for(; i >= 0; --i) {
			for(auto& u : adj[i]) {
				if(u >= i) unite(u, i);
			}
		}
		int tim3 = 0; dfs((int)D.size() - 1, tim3);
		for(int i = 0; i < Q; ++i) {
			RL[i] = ch[par[i]];
		}
		for(int i = 0; i < N; ++i) {
			pos[i].first = ch[i].first;
		}
	}
	{
		vector<int> sind(Q);
		iota(begin(sind), end(sind), 0);
		sort(begin(sind), end(sind), [&](const int& i, const int& j) { return R[i] < R[j]; });
		init(N);
		vector<int> par(Q);
		int i = 0;
		for(int j = 0; j < Q; ++j) {
			for(; i <= R[sind[j]]; ++i) {
				for(auto& u : adj[i]) {
					if(u <= i) unite(u, i);
				}
			}
			par[sind[j]] = parent(E[sind[j]]);
		}
		for(; i < N; ++i) {
			for(auto& u : adj[i]) {
				if(u <= i) unite(u, i);
			}
		}
		int tim3 = 0; dfs((int)D.size() - 1, tim3);
		for(int i = 0; i < Q; ++i) {
			RR[i] = ch[par[i]];
		}
		for(int i = 0; i < N; ++i) {
			pos[i].second = ch[i].first;
		}
	}
	vector<int> ans(Q);
	build(pos);
	for(int i = 0; i < Q; ++i) {
		ans[i] = query(RL[i].first, RL[i].second, RR[i].first, RR[i].second);
	}
	return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...