제출 #96832

#제출 시각아이디문제언어결과실행 시간메모리
96832youngyojun늑대인간 (IOI18_werewolf)C++11
100 / 100
1946 ms114752 KiB
#include "werewolf.h"
#include <bits/stdc++.h>
#define eb emplace_back
#define sz(V) ((int)(V).size())
#define allv(V) ((V).begin()),((V).end())
#define sorv(V) sort(allv(V))
#define rb(x) ((x)&(-(x)))
using namespace std;

const int MAXN = 200055;
const int MAXM = 400055;
const int MAXQ = 200055;

struct TRE {
	vector<int> G[MAXN];
	int prt[18][MAXN], cnt[MAXN], dfo[MAXN];
	int N, Rt;

	void add(int p, int v) { G[p].eb(v); }
	void dfs(int i, int &c) {
		cnt[i] = 1; dfo[i] = c++;
		for(int v : G[i]) {
			prt[0][v] = i;
			dfs(v, c);
			cnt[i] += cnt[v];
		}
	}
		
	void run() {
		prt[0][Rt] = N;
		for(int i = 18; i--;) prt[i][N] = N;
		{ int _ = 0; dfs(Rt, _); }
		for(int j = 1; j < 18; j++) for(int i = 0; i < N; i++)
			prt[j][i] = prt[j-1][prt[j-1][i]];
	}
} TA, TB;

struct BIT {
	int d[MAXN];
	void upd(int x) {
		for(x += 5; x < MAXN; x += rb(x)) d[x]++;
	}
	int get(int x) {
		int r = 0; for(x += 5; x; x -= rb(x))
			r += d[x];
		return r;
	}
} bit;

struct EVT {
	EVT(int idx, int x, int y, bool inv)
		: idx(idx), x(x), y(y), inv(inv) {}
	int idx, x, y;
	bool inv;
	bool operator < (const EVT &t) const {
		if(x != t.x) return x < t.x;
		return idx < t.idx;
	}
};
vector<EVT> EV;

vector<int> G[MAXN];
int ud[MAXN];

int A[MAXM], B[MAXM];
int CS[MAXQ], CE[MAXQ], L[MAXQ], R[MAXQ];
int Ans[MAXQ];

int N, M, Q;

int uf(int i) { return i == ud[i] ? i : (ud[i] = uf(ud[i])); }
void uf(int a, int b) { ud[uf(b)] = uf(a); }

int getMx(int v, int c) {
	for(int i = 18, p; i--;) {
		p = TA.prt[i][v];
		if(p <= c) v = p;
	}
	return v;
}
int getMn(int v, int c) {
	for(int i = 18, p; i--;) {
		p = TB.prt[i][v];
		if(c <= p && p < N) v = p;
	}
	return v;
}

void getAns() {
	for(int i = 0, a, b; i < M; i++) {
		a = A[i]; b = B[i];
		G[a].eb(b); G[b].eb(a);
	}
	TA.N = TB.N = N; TA.Rt = N-1;
	iota(ud, ud+N, 0);
	for(int i = 1; i < N; i++) for(int v : G[i]) {
		if(i < v) continue;
		v = uf(v);
		if(v != i) TA.add(i, v);
		uf(i, v);
	}
	iota(ud, ud+N, 0);
	for(int i = N; i--;) for(int v : G[i]) {
		if(v < i) continue;
		v = uf(v);
		if(v != i) TB.add(i, uf(v));
		uf(i, v);
	}
	TA.run(); TB.run();

	for(int i = 0; i < N; i++)
		EV.eb(-1, TA.dfo[i], TB.dfo[i], false);
	for(int i = 0, a, b; i < Q; i++) {
		a = getMx(CE[i], R[i]);
		b = getMn(CS[i], L[i]);
		EV.eb(i, TA.dfo[a]-1, TB.dfo[b]-1, true);
		EV.eb(i, TA.dfo[a]-1, TB.dfo[b]+TB.cnt[b]-1, false);
		a = TA.dfo[a]+TA.cnt[a]-1;
		EV.eb(i, a, TB.dfo[b]-1, false);
		EV.eb(i, a, TB.dfo[b]+TB.cnt[b]-1, true);
	}
	sorv(EV);
	for(auto &ev : EV) {
		if(ev.idx < 0) bit.upd(ev.y);
		else Ans[ev.idx] += bit.get(ev.y) * (ev.inv ? -1 : 1);
	}
}

std::vector<int> check_validity(int N, std::vector<int> X, std::vector<int> Y,
                                std::vector<int> S, std::vector<int> E,
								std::vector<int> L, std::vector<int> R) {
	::N = N; ::M = sz(X); ::Q = sz(S);
	for(int i = 0; i < M; i++) { ::A[i] = X[i]; ::B[i] = Y[i]; }
	for(int i = 0; i < Q; i++) {
		::CS[i] = S[i]; ::CE[i] = E[i];
		::L[i] = L[i]; ::R[i] = R[i];
	}
	getAns();
	vector<int> V;
	for(int i = 0; i < Q; i++) V.eb(!!Ans[i]);
	return V;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...