답안 #591827

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
591827 2022-07-08T01:05:47 Z tutis Flight to the Ford (BOI22_communication) C++17
15 / 100
898 ms 2068 KB
#pragma GCC optimize ("O3")
#pragma GCC target("avx,avx2,fma")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
int prob = 500;
#include "communication.h"
struct intervalset
{
	int sz = 0;
	vector<pair<int, int>>S;//sorted, disjoint
	intervalset()
	{

	}
	intervalset(int N)
	{
		sz = N;
		S.push_back({1, N});
	}
	void append(pair<int, int> v)
	{
		sz += v.second - v.first + 1;
		if (S.empty())
			S.push_back(v);
		else {
			assert(v.first > S.back().second);
			if (v.first == S.back().second + 1)
				S.back().second = v.second;
			else
				S.push_back(v);
		}
	}
	pair<intervalset, intervalset> split(int k)
	{	//k,sz-k
		intervalset A;
		intervalset B;
		for (pair<int, int>i : S)
		{
			if (i.second - i.first + 1 <= k)
			{
				A.append(i);
				k -= i.second - i.first + 1;
			}
			else if (k <= 0)
			{
				B.append(i);
			}
			else
			{
				A.append({i.first, i.first + k - 1});
				B.append({i.first + k, i.second});
				k = 0;
			}
		}
		return {A, B};
	}
	int kth(int k)
	{
		for (pair<int, int>i : S)
		{
			if (i.second - i.first + 1 < k)
			{
				k -= i.second - i.first + 1;
			}
			else
			{
				return i.first + (k - 1);
			}
		}
		assert(false);
		return 0;
	}
	int kelintas(int x)
	{
		int r = 0;
		for (pair<int, int>i : S)
		{
			if (i.second < x)
				r += (i.second - i.first + 1);
			else if (x < i.first)
				return 0;
			else
				return r + (x - i.first + 1);
		}
		return 0;
	}
	intervalset(const intervalset &A, const intervalset &B)
	{
		const vector<pair<int, int>>&a = A.S;
		const vector<pair<int, int>>&b = B.S;
		int i = 0;
		int j = 0;
		while (i < (int)a.size() && j < (int)b.size())
		{
			if (a[i].first < b[j].first)
				append(a[i++]);
			else
				append(b[j++]);
		}
		while (i < (int)a.size())
			append(a[i++]);
		while (j < (int)b.size())
			append(b[j++]);
	}
};
int K[100][100];
pair<int, int> getbest(int A, int B)
{
	assert(A + B < 100);
	static bool prec = false;
	if (prec == false)
	{
		prec = true;
		for (int sum = 0; sum < 100; sum++)
		{
			if (sum <= 2)
			{
				for (int a = 0; a <= sum; a++) {
					int b = sum - a;
					K[a][b] = 0;
				}
			}
			else {
				for (int a = 0; a <= sum; a++)
				{
					int b = sum - a;
					K[a][b] = 1000;
				}
				int rep = 1;
				if (sum <= 4)
					rep = 4;
				for (int r = 0; r < rep; r++)
					for (int a = 0; a <= sum; a++)
					{
						int b = sum - a;
						for (int a0 = 0; a0 <= a; a0++)
						{
							for (int b0 = 0; b0 <= b; b0++)
							{
								int a_ = a0 + b0;
								int b_ = b - b0;

								int a__ = a - a0 + b - b0;
								int b__ = a0;
								K[a][b] = min(K[a][b], 1 + max(K[a_][b_], K[a__][b__]));
							}
						}
					}
			}
		}
	}
	pair<int, pair<int, int>>best = {1000, {0, 0}};
	for (int a0 = 0; a0 <= A; a0++)
	{
		for (int b0 = 0; b0 <= B; b0++)
		{
			int a_ = a0 + b0;
			int b_ = B - b0;

			int a__ = A - a0 + B - b0;
			int b__ = a0;
			best = min(best, {max(K[a_][b_], K[a__][b__]), {a0, b0}});
		}
	}
	return best.second;
}
void encode(int N, int X)
{
	intervalset A(N);
	intervalset B;
	mt19937 rng(0);
	while (A.sz + B.sz > 2)
	{
		int a0 = A.sz / 2;
		int b0 = B.sz / 2;
		if (A.sz + B.sz < 100)
		{
			pair<int, int>c = getbest(A.sz, B.sz);
			a0 = c.first;
			b0 = c.second;
		}
		intervalset C(A, B);
		int ka = A.kelintas(X);
		int kb = B.kelintas(X);
		int s = 1;
		if (ka != 0 && ka <= a0)
			s = 0;
		if (kb != 0 && kb <= b0)
			s = 0;
		pair<intervalset, intervalset>A_ = A.split(a0);
		pair<intervalset, intervalset>B_ = B.split(b0);
		int r = send(s);
		if (r == 0)
		{
			A = intervalset(A_.first, B_.first);
			B = A_.second;
		}
		else
		{
			A = intervalset(A_.second, B_.second);
			B = A_.first;
		}
	}
}
pair<int, int> decode(int N)
{
	intervalset A(N);
	intervalset B;
	mt19937 rng(0);
	while (A.sz + B.sz > 2)
	{
		int b0 = B.sz / 2;
		int a0 = A.sz / 2;
		if (A.sz + B.sz < 100)
		{
			pair<int, int>c = getbest(A.sz, B.sz);
			a0 = c.first;
			b0 = c.second;
		}
		pair<intervalset, intervalset>A_ = A.split(a0);
		pair<intervalset, intervalset>B_ = B.split(b0);
		int r = receive();
		if (r == 0)
		{
			A = intervalset(A_.first, B_.first);
			B = A_.second;
		}
		else
		{
			A = intervalset(A_.second, B_.second);
			B = A_.first;
		}
	}
	if (A.sz == 0)
		return {B.S[0].first, B.S.back().second};
	if (B.sz == 0)
		return {A.S[0].first, A.S.back().second};
	return {A.S[0].first, B.S[0].first};
}
// int main()
// {
// 	for (int test = 0; test < 20; test++)
// 	{
// 		int N = 1e9;
// 		int X = 3;
// 		encode(N, X);
// 		pair<int, int>a = decode(N);
// 		assert(a.first >= 1 && a.first <= N && a.second >= 1 && a.second <= N);
// 		assert(a.first == X || a.second == X);
// 		cout << kiekis << endl;
// 		kiekis = 0;
// 	}
// }
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 1896 KB Output is correct
2 Correct 15 ms 1788 KB Output is correct
3 Correct 23 ms 1836 KB Output is correct
4 Correct 15 ms 1880 KB Output is correct
5 Correct 16 ms 1804 KB Output is correct
6 Correct 43 ms 2068 KB Output is correct
7 Correct 44 ms 1876 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Partially correct 898 ms 1820 KB Output is partially correct
2 Incorrect 7 ms 296 KB Not correct
3 Halted 0 ms 0 KB -