Submission #240638

#TimeUsernameProblemLanguageResultExecution timeMemory
240638faremy건물 4 (JOI20_building4)C++14
100 / 100
498 ms71944 KiB
#include <iostream>
#include <algorithm>
#include <vector>


const int MAXN = 1e6 + 2;
const int INFTY = 2e9;

int plan[2][MAXN];
int color[MAXN];

struct Ans {
	Ans() : size(-INFTY), pos(-1), prev(-1) {}
	Ans(int s, int p, int pr) : size(s), pos(p), prev(pr) {};

	int size, pos, prev;
	bool operator >(const Ans &other) const
	{
		return (size > other.size);
	}
} lis[2][MAXN];


std::vector<int> findlis(int size)
{
	std::fill_n((Ans *)lis, 2 * MAXN, Ans());
	lis[0][0] = Ans(0, 0, -1);

	for (int iPos = 1; iPos <= size; iPos++)
	{
		Ans b0 = lis[0][iPos - 1];
		Ans b1 = lis[1][iPos - 1];

		if (plan[0][iPos - 1] <= plan[1][iPos] && b0 > lis[1][iPos])
			lis[1][iPos] = b0;
		if (plan[1][iPos - 1] <= plan[1][iPos] && b1 > lis[1][iPos])
			lis[1][iPos] = b1;

		b0.size++; b1.size++;
		b0.prev = b0.pos;
		b1.prev = b1.pos;
		b0.pos = b1.pos = iPos;

		if (plan[0][iPos - 1] <= plan[0][iPos] && b0 > lis[0][iPos])
			lis[0][iPos] = b0;
		if (plan[1][iPos - 1] <= plan[0][iPos] && b1 > lis[0][iPos])
			lis[0][iPos] = b1;
	}

	std::vector<int> seq;
	int pos = size;

	while (pos != -1)
	{
		seq.emplace_back(pos);
		pos = lis[0][pos].prev;
	}

	if (seq.back() != 0)
		return {};
	std::vector<int> choice;

	pos = 0;
	while (seq.size() > 1)
	{
		choice.emplace_back(0);
		seq.pop_back();

		for (pos++; pos < seq.back(); pos++)
			choice.emplace_back(1);
	}

	choice.emplace_back(0);
	return choice;
}

int cnt0(std::vector<int> vec)
{
	int c = 0;
	for (int i : vec)
		c += (i == 0);
	return c - 2;
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cout.tie(nullptr);
	std::cin.tie(nullptr);

	int half; std::cin >> half;
	int build = half * 2;

	for (int iPlan = 0; iPlan < 2; iPlan++)
	{
		plan[iPlan][build + 1] = INFTY;
		for (int iBuild = 1; iBuild <= build; iBuild++)
			std::cin >> plan[iPlan][iBuild];
	}

	std::vector<int> choiceA = findlis(build + 1);
	for (int iBuild = 1; iBuild <= build; iBuild++)
		std::swap(plan[0][iBuild], plan[1][iBuild]);
	std::vector<int> choiceB = findlis(build + 1);

	if (choiceA.empty() || choiceB.empty())
	{
		std::cout << "-1\n";
		return 0;
	}

	for (int &choose : choiceB)
		choose ^= 1;
	choiceB[0] = choiceB[build + 1] = 0;

	int maxA = cnt0(choiceA);
	int minA = cnt0(choiceB);

	if (maxA < half || minA > half)
	{
		std::cout << "-1\n";
		return 0;
	}

	std::vector<int> eq;
	for (int iPos = 0; iPos < build + 2; iPos++)
		if (choiceA[iPos] == choiceB[iPos])
			eq.emplace_back(iPos);

	for (int iSpl = 0; maxA > half; iSpl++)
	{
		int chg = 0;
		for (int iPos = eq[iSpl] + 1; iPos < eq[iSpl + 1]; iPos++)
			chg += choiceA[iPos] - choiceB[iPos];
	
		if (maxA + chg >= half)
		{
			maxA += chg;
			for (int iPos = eq[iSpl] + 1; iPos < eq[iSpl + 1]; iPos++)
				choiceA[iPos] ^= 1;
			continue;
		}

		for (int iPos = eq[iSpl] + 1; iPos < eq[iSpl + 1]; iPos++)
			color[iPos] = (plan[choiceA[iPos]][iPos] < plan[choiceB[iPos]][iPos]);
		for (int iPos = eq[iSpl] + 1; iPos < eq[iSpl + 1] && maxA > half; iPos++)
			if (color[iPos] == 1)
			{
				maxA += choiceA[iPos] - choiceB[iPos];
				choiceA[iPos] ^= 1;
			}

		for (int iPos = eq[iSpl + 1] - 1; iPos > eq[iSpl] && maxA > half; iPos--)
			if (color[iPos] == 0)
			{
				maxA += choiceA[iPos] - choiceB[iPos];
				choiceA[iPos] ^= 1;
			}
	}

	for (int iPos = 1; iPos <= build; iPos++)
		std::cout << (char)('A' + choiceA[iPos]);
	std::cout << '\n';

	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...