제출 #293794

#제출 시각아이디문제언어결과실행 시간메모리
293794staniewzki늑대인간 (IOI18_werewolf)C++17
34 / 100
1398 ms63080 KiB
#include<bits/stdc++.h>
using namespace std;
 
#define REP(i, n) for(int i = 0; i < n; i++)
#define FOR(i, a, b) for(int i = a; i <= b; i++)

#include "werewolf.h"

struct RMQ {
	vector<vector<int>> st;
	vector<int> pre;
	function<int(int, int)> f;
	RMQ(vector<int> &a, function<int(int, int)> f) : f(f) {
		int n = size(a), lg = 0;
		while((1 << lg) < n) lg++;
		st.resize(lg + 1, vector<int>(a));
		st[0] = a;
		FOR(i, 1, lg) REP(j, n) {
			st[i][j] = st[i - 1][j];
			int q = j + (1 << (i - 1));
			if(q < n) st[i][j] = f(st[i][j], st[i - 1][q]);
		}
		pre.resize(n + 1);
		FOR(i, 2, n) pre[i] = pre[i / 2] + 1;
	}
 
	int operator()(int l, int r) {
		if(l > r) swap(l, r);
		int q = pre[r - l + 1], x = r - (1 << q) + 1;
		return f(st[q][l], st[q][x]);
	}
};
vector<int> check_validity(int n, vector<int> x, vector<int> y,
                                vector<int> s, vector<int> e,
                                vector<int> l, vector<int> r) {
	int m = size(x), q = size(s);
	vector<vector<int>> adj(n);
	REP(i, m) {
		adj[x[i]].emplace_back(y[i]);
		adj[y[i]].emplace_back(x[i]);
	}

	int pos = 0;
	REP(i, n)
		if(size(adj[i]) == 1)
			pos = i;

	int last = -1;
	vector<int> order(n);
	REP(i, n) {
		order[i] = pos;
		for(int x : adj[pos]) {
			if(x != last) {
				pos = x;
				break;
			}
		}
		last = order[i];
	}

	vector<int> where(n);
	REP(i, n)
		where[order[i]] = i;

	RMQ range_min(order, [&](int a, int b) { return min(a, b); });
	RMQ range_max(order, [&](int a, int b) { return max(a, b); });

	auto get_interval = [&](int i, auto valid) {
		int l = 0, r = i;		
		while(l < r) {
			int m = (l + r) / 2;
			if(valid(m))
				r = m;
			else
				l = m + 1;
		}
		int x = l;
		l = i, r = n - 1;
		while(l < r) {
			int m = (l + r + 1) / 2;
			if(valid(m))
				l = m;
			else
				r = m - 1;
		}
		return pair<int, int>(x, l);
	};

	vector<int> ans(q);
	REP(i, q) {
		s[i] = where[s[i]], e[i] = where[e[i]];
		auto [a, b] = get_interval(s[i], [&](int j) { return range_min(s[i], j) >= l[i]; });
		auto [c, d] = get_interval(e[i], [&](int j) { return range_max(e[i], j) <= r[i]; });
		ans[i] = !(b < c || d < a);
	}
	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...