Submission #290651

#TimeUsernameProblemLanguageResultExecution timeMemory
290651maximath_1Park (JOI17_park)C++11
100 / 100
847 ms1272 KiB
#include "park.h"
#include <vector>
#include <queue>
#include <numeric>
#include <algorithm>
#include <iostream>
using namespace std;

int n;
vector<int> graph, pend;
vector<pair<int, int> > edge;

void ans(pair<int, int> i){
	int u = i.first, v = i.second;
	if(u > v) swap(u, v);
	Answer(u, v);
}

vector<int> subarray(int l, int r, vector<int> a){
	vector<int> rs;
	for(int i = l; i <= r; i ++)
		rs.push_back(a[i]);
	return rs;
}

bool is_con(int nw, vector<int> g){
	vector<int> que(n, 0);
	for(int i : g) que[i] = 1;
	que[nw] = 1;
	return Ask(min(g[0], nw), max(g[0], nw), que.data());
}

bool is_con_via(int nw, vector<int> g, vector<int> p){
	vector<int> que(n, 0);
	for(int i : g) que[i] = 1;
	for(int i : p) que[i] = 1;
	que[nw] = 1;
	return Ask(min(g[0], nw), max(g[0], nw), que.data());
}

void connect(int nd, vector<int> g){
	if(g.empty()) return;
	vector<vector<int> > adj(n);
	vector<bool> active(n, 0);
	for(int i : g) active[i] = 1;
	for(auto e : edge){
		if(active[e.first] && active[e.second]){
			adj[e.first].push_back(e.second);
			adj[e.second].push_back(e.first);
		}
	}

	vector<int> ord;
	vector<bool> vis(n, 0);
	ord.push_back(g[0]); vis[g[0]] = 1;
	queue<int> bfs; bfs.push(g[0]);

	for(; bfs.size(); bfs.pop()){
		int nw = bfs.front();
		for(int nx : adj[nw]) if(!vis[nx]){
			vis[nx] = 1;
			bfs.push(nx);
			ord.push_back(nx);
		}
	}

	if(ord.size() != g.size()){
		vector<int> g1, g2;
		for(int i : g)
			if(vis[i]) g1.push_back(i);
			else g2.push_back(i);
		connect(nd, g1);
		connect(nd, g2);
		return;
	}

	if(!is_con(nd, subarray(0, (int)ord.size() - 1, ord)))
		return;

	int id = (int)ord.size() - 1;
	for(int lf = 0, rg = id, md; lf <= rg;){
		md = (lf + rg) / 2;
		if(is_con(nd, subarray(0, md, ord))){
			id = md;
			rg = md - 1;
		}
		else
			lf = md + 1;
	}

	edge.push_back({nd, ord[id]});
	g.erase(find(g.begin(), g.end(), ord[id]));
	connect(nd, g);
}

vector<int> path;
void find_path(int l, int r){
	vector<int> c;
	if(l == 0) c = graph;
	else c = {l};

	if(is_con(r, c)) path.push_back(r);
	else{
		int id = (int)pend.size() - 1;
		for(int lf = 0, rg = id, md; lf <= rg;){
			md = (lf + rg) / 2;
			if(is_con_via(r, c, subarray(0, md, pend))){
				id = md;
				rg = md - 1;
			}else
				lf = md + 1;
		}
		find_path(l, pend[id]);
		find_path(pend[id], r);
	}
}

void Detect(int T, int N){
	n = N;
	graph.push_back(0);
	pend.resize(N - 1); 
	iota(pend.begin(), pend.end(), 1);

	for(; pend.size();){
		int nw = pend.back();
		path.clear();
		find_path(0, nw);
		for(int u : path){
			connect(u, graph);
			graph.push_back(u);
			pend.erase(find(pend.begin(), pend.end(), u));
		}
	}

	for(pair<int, int> i : edge) ans(i);
	return;
}
#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...