답안 #1080293

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1080293 2024-08-29T08:40:06 Z Elias 커다란 상품 (IOI17_prize) C++17
20 / 100
69 ms 4632 KB
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>

using namespace std;

#define ll long long

#ifdef _DEBUG

int find_best(int n);
std::vector<int> ask(int i);
#else
#include "prize.h"
#endif

int N;

vector<int> a, b;

int segSet(int l, int r, int i, int k, int x)
{
	if (l > k || r <= k)
		return b[i];
	if (l + 1 == r)
		return a[l] = b[i] = x;
	int m = (l + r) / 2;
	return b[i] = segSet(l, m, i * 2 + 1, k, x) + segSet(m, r, i * 2 + 2, k, x);
}

int segGet(int l, int r, int i, int ql, int qr)
{
	if (ql <= l && qr >= r)
		return b[i];
	if (ql >= r || qr <= l)
		return 0;
	int m = (l + r) / 2;
	return segGet(l, m, i * 2 + 1, ql, qr) + segGet(m, r, i * 2 + 2, ql, qr);
}

int asks = 0;

int getRecursive(int l, int r, int cnt_here, int cnt_l, int cnt_r)
{
	if (l >= r)
		return -1;

	cnt_here -= segGet(0, N, 0, l, r);

	if (cnt_here <= 0)
		return -1;

	int m = (l + r) / 2;
	int i = m;

	vector<int> answer;
	bool is_special = false;
	int diff_l = 0;
	int diff_r = 0;

	do
	{
		if (i == r)
			break;

		is_special = false;
		asks++;
		assert(asks < 10000);
		assert(i >= 0 && i < N);
		answer = ask(i);

		if (answer[0] + answer[1] == 0)
			return i;

		answer[0] -= cnt_l;
		answer[1] -= cnt_r;

		if (answer[0] + answer[1] != cnt_here)
		{
			is_special = true;
			i++;
		}
		else
		{
			answer[0] -= i - m;
			diff_l += i - m;
			diff_r += i - m;
		}
	} while (is_special);

	int left = -1;
	if (i == r)
		left = getRecursive(l, m, cnt_here - (i - m), cnt_l, cnt_r + (i - m));
	else
		left = getRecursive(l, m, answer[0], cnt_l, cnt_r + answer[1] + diff_r);

	if (left != -1)
		return left;

	return getRecursive(i + 1, r, answer[1], cnt_l + answer[0] + diff_l, cnt_r);
}

int find_best(int n)
{
	N = n;

	a.resize(n);
	b.resize(4 * n);

	vector<pair<int, int>> cnt_here;

	for (int k = 0; k < 800; k++)
	{
		int i = rand() % n;

		vector<int> answer = ask(i);

		if (answer[0] + answer[1] == 0)
			return i;

		cnt_here.push_back({answer[0] + answer[1], i});
	}

	sort(cnt_here.begin(), cnt_here.end());

	for (auto [x, i] : cnt_here) {
		if (x != cnt_here.back().first) {
			segSet(0, N, 0, i, 1);
		}
	}

	int result = getRecursive(0, n, cnt_here.back().first, 0, 0);

	assert(result != -1);

	vector<int> answer = ask(result);

	assert(answer[0] + answer[1] == 0);

	return result;
}

#ifdef _DEBUG

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

static const int max_q = 10000;
static int n;
static int query_count = 0;
static vector<int> g;
static vector<vector<int>> rank_count;

vector<int> ask(int i)
{
	query_count++;
	if (query_count > max_q)
	{
		cerr << "Query limit exceeded" << endl;
		exit(0);
	}

	if (i < 0 || i >= n)
	{
		cerr << "Bad index: " << i << endl;
		exit(0);
	}

	vector<int> res(2);
	res[0] = rank_count[g[i] - 1][i + 1];
	res[1] = rank_count[g[i] - 1][n] - res[0];
	return res;
}

int main()
{
	for (int t = 10; t <= 97; t++)
	{
		string path = "/home/elias/Downloads/ioi2017tests/prize/tests/2-" + to_string(t) + ".out";
		freopen(path.c_str(), "r", stdin);

		string blub;
		cin >> blub;

		cin >> n;
		cin >> blub >> blub;

		query_count = 0;
		g.clear();
		rank_count.clear();
		asks = 0;

		g.resize(n);
		for (int i = 0; i < n; i++)
		{
			cin >> g[i];
			if (g[i] < 1)
			{
				cerr << "Invalid rank " << g[i] << " at index " << i << endl;
				exit(0);
			}
		}

		int max_rank = *max_element(g.begin(), g.end());

		rank_count.resize(max_rank + 1, vector<int>(n + 1, 0));
		for (int r = 0; r <= max_rank; r++)
		{
			for (int i = 1; i <= n; i++)
			{
				rank_count[r][i] = rank_count[r][i - 1];
				if (g[i - 1] == r)
					rank_count[r][i]++;
			}
		}

		for (int i = 0; i <= n; i++)
			for (int r = 1; r <= max_rank; r++)
				rank_count[r][i] += rank_count[r - 1][i];

		int res = find_best(n);
		assert(g[res] == 1);
		cout << res << " " << g[res]  << endl
			 << "Query count: " << query_count << endl;
	}
	return 0;
}

#endif
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 4188 KB Output is correct
2 Correct 7 ms 4184 KB Output is correct
3 Correct 5 ms 4184 KB Output is correct
4 Correct 9 ms 4356 KB Output is correct
5 Correct 6 ms 4368 KB Output is correct
6 Correct 8 ms 4184 KB Output is correct
7 Correct 9 ms 4384 KB Output is correct
8 Correct 7 ms 4440 KB Output is correct
9 Correct 8 ms 4440 KB Output is correct
10 Correct 5 ms 4184 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 4184 KB Output is correct
2 Correct 7 ms 4376 KB Output is correct
3 Correct 8 ms 4388 KB Output is correct
4 Correct 4 ms 4380 KB Output is correct
5 Correct 8 ms 4184 KB Output is correct
6 Correct 8 ms 4632 KB Output is correct
7 Correct 5 ms 4184 KB Output is correct
8 Correct 6 ms 4184 KB Output is correct
9 Correct 6 ms 4388 KB Output is correct
10 Correct 8 ms 4184 KB Output is correct
11 Correct 8 ms 4440 KB Output is correct
12 Correct 7 ms 4384 KB Output is correct
13 Correct 9 ms 4380 KB Output is correct
14 Incorrect 69 ms 852 KB Incorrect
15 Halted 0 ms 0 KB -