Submission #758329

#TimeUsernameProblemLanguageResultExecution timeMemory
758329SanguineChameleonArchery (IOI09_archery)C++17
100 / 100
256 ms12532 KiB
#include <bits/stdc++.h>
using namespace std;

void just_do_it();

int main() {
	#ifdef KAMIRULEZ
		freopen("kamirulez.inp", "r", stdin);
		freopen("kamirulez.out", "w", stdout);
	#endif
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	just_do_it();
	return 0;
}

const int WHITE = 0;
const int GRAY = 1;
const int BLACK = 2;

const int maxN = 2e5 + 20;
int a[maxN * 2];
pair<int, int> memo[maxN];
int N, R, K;

int get_color(int X) {
	if (X > K) {
		return WHITE;
	}
	else if (X < K) {
		return BLACK;
	}
	else {
		return GRAY;
	}
}

namespace sub1 {
	int cnt[maxN * 4][3];
	int sum[3];

	pair<int, int> simulate(int start) {
		for (int i = 0; i < maxN * 4; i++) {
			for (int j = 0; j < 3; j++) {
				cnt[i][j] = 0;
			}
		}
		for (int i = 0; i < 3; i++) {
			sum[i] = 0;
		}
		int color1 = -1;
		int color2 = -1;
		for (int i = 1; i <= start * 2 - 1; i++) {
			int color = get_color(a[i]);
			int pos = (i + 1) / 2;
			if (pos == 1) {
				if (color1 == -1) {
					color1 = color;
				}
				else {
					color2 = color;
				}
			}
			else {
				cnt[pos][color]++;
			}
		}
		if (start == 1) {
			if (color1 == -1) {
				color1 = GRAY;
			}
			else {
				color2 = GRAY;
			}
		}
		else {
			cnt[start][GRAY]++;
		}
		for (int i = start * 2; i <= N * 2 - 1; i++) {
			int color = get_color(a[i]);
			int pos = i / 2 + 1;
			if (pos == 1) {
				if (color1 == -1) {
					color1 = color;
				}
				else {
					color2 = color;
				}
			}
			else {
				cnt[pos][color]++;
			}
		}
		int first_gray = -1;
		int wraps = 0;
		for (int round = 1; round <= N * 3; round++) {
			if (round > N * 2 && (color1 == GRAY || color2 == GRAY)) {
				first_gray = round - 1;
				break;
			}
			if (color1 < color2) {
				swap(color1, color2);
			}
			if (color2 == GRAY) {
				wraps++;
			}
			cnt[round + N][color2]++;
			for (int i = 0; i < 3; i++) {
				sum[i] += cnt[round + 1][i];
			}
			for (int i = 2; i >= 0; i--) {
				if (sum[i] > 0) {
					color2 = i;
					sum[i]--;
					break;
				}
			}
		}
		if (R > first_gray) {
			wraps++;
		}
		int pos = (first_gray + N - R) % N + 1;
		return make_pair(pos, wraps);
	}
}


namespace sub2 {
	int cnt[maxN][2];
	int sum[3];

	pair<int, int> simulate(int start) {
		for (int i = 0; i < maxN; i++) {
			for (int j = 0; j < 3; j++) {
				cnt[i][j] = 0;
			}
		}
		for (int i = 0; i < 3; i++) {
			sum[i] = 0;
		}
		for (int i = 1; i <= start * 2 - 1; i++) {
			int color = get_color(a[i]);
			int pos = (i + 1) / 2;
			if (color != BLACK) {
				cnt[pos][color]++;
			}
		}
		cnt[start][GRAY]++;
		for (int i = start * 2; i <= N * 2 - 1; i++) {
			int color = get_color(a[i]);
			int pos = i / 2 + 1;
			if (color != BLACK) {
				cnt[pos][color]++;
			}
		}
		int pos = N;
		int wraps = 0;
		for (int iter = 0; iter < N * 3; iter++) {
			sum[WHITE] += cnt[pos][WHITE];
			sum[GRAY] += cnt[pos][GRAY];
			cnt[pos][WHITE] = 0;
			cnt[pos][GRAY] = 0;
			if (sum[WHITE] + sum[GRAY] >= 2) {
				if (pos == 1) {
					if (sum[GRAY] == 1) {
						cnt[pos][GRAY]++;
						sum[GRAY]--;
					}
					else {
						cnt[pos][WHITE]++;
						sum[WHITE]--;
					}
				}
				else {
					cnt[pos][WHITE]++;
					sum[WHITE]--;
				}
			}
			else if (sum[WHITE] + sum[GRAY] == 1) {
				if (pos == 1) {
					if (sum[GRAY] == 1) {
						wraps++;
					}
				}
				else {
					if (sum[WHITE] == 1) {
						cnt[pos][WHITE]++;
						sum[WHITE]--;
					}
					else {
						cnt[pos][GRAY]++;
						sum[GRAY]--;
					}
				}
			}
			if (pos == 1) {
				pos = N;
			}
			else {
				pos--;
			}
		}
		pos = -1;
		for (int i = 1; i <= N; i++) {
			if (cnt[i][GRAY] == 1) {
				pos = i;
				break;
			}
		}
		return make_pair(pos, wraps);
	}
}

pair<int, int> get_final(int start) {
	if (memo[start].first != -1) {
		return memo[start];
	}
	if (K <= N + 1) {
		return (memo[start] = sub1::simulate(start));
	}
	else {
		return (memo[start] = sub2::simulate(start));
	}
}

pair<int, int> solve(int lt, int rt) {
	pair<int, int> final_lt = get_final(lt);
	pair<int, int> final_rt = get_final(rt);
	if (final_lt.second > final_rt.second) {
		int tmp_lt = lt;
		int tmp_rt = rt;
		int cut = -1;
		while (lt <= rt) {
			int mt = (lt + rt) / 2;
			pair<int, int> final_mt = get_final(mt);
			if (final_mt.second == final_lt.second) {
				cut = mt;
				lt = mt + 1;
			}
			else {
				rt = mt - 1;
			}
		}
		lt = tmp_lt;
		rt = tmp_rt;
		pair<int, int> res1 = solve(lt, cut);
		pair<int, int> res2 = solve(cut + 1, rt);
		if (res1.first < res2.first) {
			return res1;
		}
		else {
			return res2;
		}
	}
	else {
		pair<int, int> res = make_pair(-1, -1);
		while (lt <= rt) {
			int mt = (lt + rt) / 2;
			pair<int, int> final_mt = get_final(mt);
			if (final_mt.first == final_lt.first) {
				res = make_pair(final_mt.first, mt);
				lt = mt + 1;
			}
			else {
				rt = mt - 1;
			}
		}
		return res;
	}
}

void just_do_it() {
	cin >> N >> R >> K;
	R = N * 2 + R % N;
	for (int i = 1; i <= N * 2 - 1; i++) {
		cin >> a[i];
	}
	if (N == 1) {
		cout << 1;
		return;
	}
	if (K == 1) {
		cout << N;
		return;
	}
	if (K == N * 2) {
		cout << 2;
		return;
	}
	for (int i = 1; i <= N; i++) {
		memo[i] = make_pair(-1, -1);
	}
	auto res = solve(1, N);
	cout << res.second;
}

Compilation message (stderr)

archery.cpp: In function 'std::pair<int, int> sub2::simulate(int)':
archery.cpp:135:15: warning: iteration 2 invokes undefined behavior [-Waggressive-loop-optimizations]
  135 |     cnt[i][j] = 0;
      |     ~~~~~~~~~~^~~
archery.cpp:134:22: note: within this loop
  134 |    for (int j = 0; j < 3; j++) {
      |                    ~~^~~
archery.cpp:135:13: warning: array subscript 2 is above array bounds of 'int [2]' [-Warray-bounds]
  135 |     cnt[i][j] = 0;
      |     ~~~~~~~~^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...