답안 #372357

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
372357 2021-02-27T20:15:34 Z LucaDantas 마상시합 토너먼트 (IOI12_tournament) C++17
100 / 100
119 ms 10860 KB
#include<cstdio>
#include<set>
using namespace std;
constexpr int maxn = 1e5+10, logn = 20;

struct BIT
{
	int bit[maxn];
	void upd(int x, int v) {
		for(; x < maxn; x += x&-x)
			bit[x] += v;
	}
	int query(int x) {
		int ans = 0;
		for(; x > 0; x -= x&-x)
			ans += bit[x];
		return ans;
	}
	int bs(int v) {
		int pos = 0, st = v;
		for(int l = logn; l >= 0; l--) {
			if(pos + (1 << l) >= maxn) continue;
			if(bit[pos + (1 << l)] < v) {
				pos += (1 << l);
				v -= bit[pos];
			}
		}
		return pos+(st>0);
	}
} bit;

struct SegmentTree
{
	int tree[4*maxn], a[maxn];
	void build(int node, int i, int j) {
		if(i == j) return (void)(tree[node] = a[i]);
		int m = (i+j) >> 1;
		build(2*node, i, m); build(2*node+1, m+1, j);
		tree[node] = max(tree[2*node], tree[2*node+1]);
	}
	int query(int node, int i, int j, int l, int r) {
		if(i > r || j < l) return 0;
		if(i >= l && j <= r) return tree[node];
		int m = (i+j) >> 1;
		return max(query(2*node, i, m, l, r), query(2*node+1, m+1, j, l, r));
	}
} seg;

int s[maxn], e[maxn], pref[maxn];

int GetBestPosition(int N, int C, int R, int *K, int *S, int *E) {
	set<int> st;
	for(int i = 1; i <= N; i++)
		bit.upd(i, 1), st.insert(i), seg.a[i] = K[i-1];

	seg.build(1, 1, N-1);

	for(int i = 0; i < C; i++) {
		++E[i], ++S[i];
		s[i] = bit.bs(S[i]-1) + 1;
		e[i] = bit.bs(E[i]);
		auto it = st.lower_bound(s[i]);
		while(next(it) != st.end() && *next(it) <= e[i])
			bit.upd(*it, -1), it = st.erase(it);
		// printf("%d %d\n", s[i], e[i]);
		// for(int i = 1; i <= N; i++)
		// 	printf("%d ", bit.query(i));
		// printf("\n");

		// já calculo a resp aq
		int v = seg.query(1, 1, N-1, s[i], e[i]-1); // -1 pq o ultimo sai
		// printf("%d %d %d\n", s[i], e[i]-1, v);
		if(v < R) ++pref[s[i]], --pref[e[i]];
		// nem precisa congelar no else pq agr esse intervalo
		// ta junto, ent o máximo sempre vai ser maior q v
	}
	int ans = 0;
	for(int i = 1; i <= N; i++) {
		pref[i] += pref[i-1];
		// printf("pref[%d] == %d\n", i, pref[i]);
		if(pref[ans] < pref[i])
			ans = i;
	}
	return max(0, ans-1);
}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 364 KB Output is correct
2 Correct 1 ms 384 KB Output is correct
3 Correct 1 ms 364 KB Output is correct
4 Correct 1 ms 364 KB Output is correct
5 Correct 1 ms 364 KB Output is correct
6 Correct 1 ms 364 KB Output is correct
7 Correct 1 ms 364 KB Output is correct
8 Correct 1 ms 364 KB Output is correct
9 Correct 1 ms 364 KB Output is correct
10 Correct 1 ms 364 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 492 KB Output is correct
2 Correct 5 ms 876 KB Output is correct
3 Correct 3 ms 748 KB Output is correct
4 Correct 5 ms 876 KB Output is correct
5 Correct 5 ms 876 KB Output is correct
6 Correct 5 ms 876 KB Output is correct
7 Correct 5 ms 876 KB Output is correct
8 Correct 5 ms 876 KB Output is correct
9 Correct 3 ms 768 KB Output is correct
10 Correct 6 ms 876 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 56 ms 4608 KB Output is correct
2 Correct 109 ms 10732 KB Output is correct
3 Correct 49 ms 8428 KB Output is correct
4 Correct 103 ms 10732 KB Output is correct
5 Correct 101 ms 10476 KB Output is correct
6 Correct 119 ms 9984 KB Output is correct
7 Correct 106 ms 10860 KB Output is correct
8 Correct 115 ms 10732 KB Output is correct
9 Correct 48 ms 8172 KB Output is correct
10 Correct 53 ms 8300 KB Output is correct