답안 #139956

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
139956 2019-08-01T17:50:40 Z aminra CEOI16_icc (CEOI16_icc) C++17
100 / 100
155 ms 632 KB
#include <bits/stdc++.h>
#include "icc.h"
using namespace std;
typedef long long ll;
typedef long double ld;
const int MAXN = (int)103;
const ll infint = (int)1e9 + 3;
const int MOD = (int)1e9 + 7;
const ll inf = (ll)1e18 + 3;
vector<int> comp[MAXN];
int par[MAXN];
int get(int a)
{
	if(par[a] == a)
		return a;
	return par[a] = get(par[a]);
}
void merge(int a, int b)
{
	if((a = get(a)) == (b = get(b)))
		return;
	if(comp[a].size() < comp[b].size())
		swap(a, b);
	par[b] = a;
	for (auto u : comp[b])
		comp[a].push_back(u);
	comp[b].clear();
}
void solve(int n)
{
	vector<int> mai;
	for (int i = 1; i <= n; i++)
		if(par[i] == i)
			mai.push_back(i);
	int lg = 0, idx = 1, sz = mai.size();
	while(idx <= sz)
		idx <<= 1, lg++;
	lg--;
	int xo = 0;
	for (int i = 0; i <= lg; i++)
	{
		vector<int> query0, query1;
		for (int j = 0; j < sz; j++)
			if((j >> i) & 1)	
			{
				for (auto x : comp[mai[j]])
					query1.push_back(x);
			}
			else
			{
				for (auto x : comp[mai[j]])
					query0.push_back(x);
			}
		int ans = 0;
		if(query0.size() && query1.size())
			ans = query(query0.size(), query1.size(), query0.data(), query1.data());
		if(ans == 1)
			xo += (1 << i);
	}
	vector<pair<int, int> > matching;
	for (int i = 0; i < sz; i++)	
	{
		int match = (i ^ xo);
		if(match < sz && i < match)
			matching.push_back({i, match});
	}	
	sz = matching.size();
	int L = -1, R = sz - 1;
	while(R - L > 1)
	{
		int mid = (L + R) >> 1;
		vector<int> query0, query1;
		for (int i = 0; i <= mid; i++)	
		{
			int id0 = mai[matching[i].first];
			for (auto x : comp[id0])
				query0.push_back(x);
			int id1 = mai[matching[i].second];
			for (auto x : comp[id1])
				query1.push_back(x);
		}
		int ans = query(query0.size(), query1.size(), query0.data(), query1.data());
		if(ans == 1)	
			R = mid;
		else
			L = mid;
	}
	int x = mai[matching[R].first], y = mai[matching[R].second];
	vector<int> cmp[2];
	for (auto u : comp[x])
		cmp[0].push_back(u);
	for (auto u : comp[y])
		cmp[1].push_back(u);
	for (int j = 0; j < 2; j++)
	{
		while(cmp[j].size() > 1)
		{
			int ans = query(cmp[j].size() / 2, cmp[j ^ 1].size(), cmp[j].data(), cmp[j ^ 1].data());
			if(ans)
				cmp[j].erase(cmp[j].begin() + cmp[j].size() / 2, cmp[j].end());
			else
				cmp[j].erase(cmp[j].begin(), cmp[j].begin() + cmp[j].size() / 2);
		}
	}
	int u = cmp[0][0], v = cmp[1][0];
	setRoad(u, v);
	merge(u, v);
	return;
}
void run(int n)
{
	for (int i = 1; i <= n; i++)
		par[i] = i, comp[i].push_back(i);
	int edges = n - 1;
	while(edges--)
		solve(n);
}
# 결과 실행 시간 메모리 Grader output
1 Correct 10 ms 632 KB Ok! 110 queries used.
2 Correct 9 ms 504 KB Ok! 108 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 48 ms 560 KB Ok! 611 queries used.
2 Correct 41 ms 592 KB Ok! 504 queries used.
3 Correct 42 ms 504 KB Ok! 539 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 148 ms 632 KB Ok! 1515 queries used.
2 Correct 133 ms 560 KB Ok! 1206 queries used.
3 Correct 150 ms 572 KB Ok! 1539 queries used.
4 Correct 150 ms 556 KB Ok! 1509 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 150 ms 504 KB Ok! 1515 queries used.
2 Correct 154 ms 556 KB Ok! 1516 queries used.
3 Correct 152 ms 596 KB Ok! 1488 queries used.
4 Correct 152 ms 592 KB Ok! 1534 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 147 ms 556 KB Ok! 1456 queries used.
2 Correct 154 ms 604 KB Ok! 1506 queries used.
3 Correct 146 ms 504 KB Ok! 1356 queries used.
4 Correct 155 ms 600 KB Ok! 1519 queries used.
5 Correct 151 ms 504 KB Ok! 1528 queries used.
6 Correct 149 ms 560 KB Ok! 1533 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 144 ms 504 KB Ok! 1376 queries used.
2 Correct 137 ms 560 KB Ok! 1270 queries used.