답안 #1055672

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1055672 2024-08-13T02:57:09 Z Gromp15 식물 비교 (IOI20_plants) C++17
100 / 100
761 ms 85420 KB
#include <bits/stdc++.h>
#define ll long long
#include "plants.h"
#define ar array
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()
using namespace std;
template<typename T> bool ckmin(T &a, const T &b) { return a > b ? a = b, 1 : 0; }
template<typename T> bool ckmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }

const int INF = 1e9;

struct seg {
	int N; vector<ar<int, 2>> tree; vector<int> lazy;
	void pull(int node) {
		tree[node] = min(tree[node*2], tree[node*2+1]);
	}
	void push(int node) {
		if (!lazy[node]) return;
		tree[node][0] += lazy[node];
		if (node < N) lazy[node*2] += lazy[node], lazy[node*2+1] += lazy[node];
		lazy[node] = 0;
	}
	seg(int n, const vector<int>& r) : N(1<<(__lg(n)+1)), tree(2*N), lazy(2*N) {
		for (int i = 0; i < n; i++) tree[i+N] = {r[i], i};
		for (int i = N-1; i >= 1; i--) pull(i);
	}
	ar<int, 2> query(int node, int nl, int nr, int ql, int qr) {
		push(node);
		if (ql > nr || qr < nl) return {INF};
		if (ql <= nl && nr <= qr) return tree[node];
		int mid = (nl+nr)/2;
		return min(query(node*2, nl, mid, ql, qr), query(node*2+1, mid+1, nr, ql, qr));
	}
	void update(int node, int nl, int nr, int ql, int qr, int v) {
		push(node);
		if (ql > nr || qr < nl) return;
		if (ql <= nl && nr <= qr) {
			lazy[node] += v; push(node); return;
		}
		int mid = (nl+nr)/2;
		update(node*2, nl, mid, ql, qr, v), update(node*2+1, mid+1, nr, ql, qr, v);
		pull(node);
	}
};

struct seg2 {
	int N; vector<ar<int, 2>> tree;
	seg2(int n) : N(1<<(__lg(n)+1)), tree(2*N, {INF}) {}
	void update(int pos, ar<int, 2> nw) {
		for (int i = pos + N; i; i >>= 1) ckmin(tree[i], nw);
	}
	ar<int, 2> query(int node, int nl, int nr, int ql, int qr) {
		if (ql > nr || qr < nl) return {INF};
		if (ql <= nl && nr <= qr) return tree[node];
		int mid = (nl+nr)/2;
		return min(query(node*2, nl, mid, ql, qr), query(node*2+1, mid+1, nr, ql, qr));
	}
};

const int LOG = 19;

int n, k;
vector<int> got;
vector<vector<int>> toL, toR;

int dist(int x) {
	return x < 0 ? x + n : x;
}

void init(int _k, std::vector<int> r) {
	k = _k;
	n = sz(r);
	seg st(n, r);
	got.resize(n);
	set<int> in;
	set<ar<int, 2>> where;
	auto add = [&](int pos) {
		//cout << "Add " << pos << endl;
		assert(!in.count(pos));
		if (in.size() > 1) {
			auto it = in.lower_bound(pos);
			int R = it != in.end() ? *it : *in.begin();
			int L = it != in.begin() ? *prev(it) : *prev(in.end());
			assert(where.count({dist(R - L), R}));
			where.erase({dist(R - L), R});
			where.insert({dist(R - pos), R});
			where.insert({dist(pos - L), pos});
		}
		else if (in.size() == 1) {
			int other = *in.begin();
			assert(where.size() == 1);
			assert((*where.begin())[0] == n);
			where.erase(where.begin());
			where.insert({dist(other - pos), other});
			where.insert({dist(pos - other), pos});
		}
		else {
			where.insert({n, pos});
		}
		in.insert(pos);
	};
	auto rem = [&](int pos) {
		//cout << "Rem " << pos << endl;
		assert(in.count(pos));
		if (in.size() == 1) {
			in.erase(in.begin());
			where.erase(where.begin());
		}
		else if (in.size() == 2) {
			int other = *in.begin() == pos ? *next(in.begin()) : *in.begin();
			assert(where.count({dist(pos - other), pos}));
			in.erase(pos);
			where.erase(where.begin());
			where.erase(where.begin());
			where.insert({n, other});
		}
		else {
			auto it = in.upper_bound(pos);
			int R = it != in.end() ? *it : *in.begin();
			auto it2 = in.lower_bound(pos);
			int L = it2 != in.begin() ? *prev(it2) : *prev(in.end());
			assert(where.count({dist(R - pos), R}));
			assert(where.count({dist(pos - L), pos}));
			where.erase({dist(R - pos), R});
			where.erase({dist(pos - L), pos});
			where.insert({dist(R - L), R});
			in.erase(pos);
		}
	};
	int on = n;
	while (1) {
		auto q = st.query(1, 0, st.N-1, 0, n-1);
		if (!q[0]) { 
			add(q[1]);
			st.update(1, 0, st.N-1, q[1], q[1], INF);
		}
		else {
			if (where.empty()) break;
			auto [val, pos] = *prev(where.end());
			assert(val >= k);
			rem(pos);
			got[pos] = on--;
			int L = pos - k + 1, R = pos - 1;
			if (L < 0) L += n;
			if (R < 0) R += n;
			if (L <= R) st.update(1, 0, st.N-1, L, R, -1);
			else {
				st.update(1, 0, st.N-1, 0, R, -1);
				st.update(1, 0, st.N-1, L, n-1, -1);
			}
		}
	}
	toL.resize(LOG, vector<int>(2 * n, 2 * n));
	toR.resize(LOG, vector<int>(2 * n, -1));
	vector<int> idx(n);
	iota(all(idx), 0);
	sort(all(idx), [&](int x, int y) { return got[x] > got[y]; });
	seg2 st2(2 * n);
	auto query = [&](int l, int r) {
		return st2.query(1, 0, st2.N-1, max(0, l), min(2*n-1, r));
	};
	for (int i = 0; i < n; i++) {
		int pos = idx[i];
		for (int d : {0, n}) {
			auto l = query(pos + d - k + 1, pos + d - 1);
			toL[0][pos + d] = l[0] == INF ? 2 * n : l[1];
			auto r = query(pos + d + 1, pos + d + k - 1);
			toR[0][pos + d] = r[0] == INF ? -1 : r[1];
			st2.update(pos, ar<int, 2>{got[pos], pos});
			st2.update(pos + d, ar<int, 2>{got[pos], pos + d});
		}
	}
	for (int i = 1; i < LOG; i++) {
		for (int j = 0; j < 2 * n; j++) {
			toL[i][j] = toL[i-1][j] < 2 * n ? toL[i-1][toL[i-1][j]] : 2 * n;
			toR[i][j] = ~toR[i-1][j] ? toR[i-1][toR[i-1][j]] : -1;
		}
	}
}

bool win_left(int x, int y) {
	if (x >= y) {
		for (int i = LOG-1; i >= 0; i--) if (toL[i][x] < 2 * n && toL[i][x] >= y + (k - 1)) x = toL[i][x];
		if (x <= y + (k - 1) && got[x % n] <= got[y % n]) return 1;
		x = toL[0][x];
		return x < 2 * n && x >= y - (k - 1) && got[x % n] <= got[y % n];
	}
	else {
		x += n;
		for (int i = LOG-1; i >= 0; i--) if (toL[i][x] < 2 * n && toL[i][x] >= y + (k - 1)) x = toL[i][x];
		if (x <= y + (k - 1) && got[x % n] <= got[y % n]) return 1;
		x = toL[0][x];
		return x < 2 * n && x >= y - (k - 1) && got[x % n] <= got[y % n];
	}
}
bool win_right(int x, int y) {
	if (x <= y) {
		for (int i = LOG-1; i >= 0; i--) if (~toR[i][x] && toR[i][x] <= y - (k - 1)) x = toR[i][x];
		if (x >= y - (k - 1) && got[x % n] <= got[y % n]) return 1;
		x = toR[0][x];
		return ~x && x <= y + k - 1 && got[x % n] <= got[y % n];
	}
	else {
		y += n;
		for (int i = LOG-1; i >= 0;  i--) if (~toR[i][x] && toR[i][x] <= y - (k - 1)) x = toR[i][x];
		if (x >= y - (k - 1) && got[x % n] <= got[y % n]) return 1;
		x = toR[0][x];
		return ~x && x <= y + k - 1 && got[x % n] <= got[y % n];
	}
}

bool win(int x, int y) {
	return win_left(x, y) || win_right(x, y);
}

int compare_plants(int x, int y) {
	int w1 = win(x, y), w2 = win(y, x);
	return (!w1 && !w2) || (w1 && w2) ? 0 : w1 ? -1 : 1;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 0 ms 348 KB Output is correct
4 Correct 0 ms 348 KB Output is correct
5 Correct 0 ms 348 KB Output is correct
6 Correct 38 ms 4028 KB Output is correct
7 Correct 105 ms 13392 KB Output is correct
8 Correct 497 ms 84112 KB Output is correct
9 Correct 524 ms 84064 KB Output is correct
10 Correct 551 ms 84496 KB Output is correct
11 Correct 590 ms 84964 KB Output is correct
12 Correct 601 ms 83952 KB Output is correct
13 Correct 694 ms 83280 KB Output is correct
14 Correct 392 ms 83496 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 604 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 0 ms 348 KB Output is correct
4 Correct 0 ms 348 KB Output is correct
5 Correct 0 ms 348 KB Output is correct
6 Correct 3 ms 792 KB Output is correct
7 Correct 57 ms 6580 KB Output is correct
8 Correct 2 ms 348 KB Output is correct
9 Correct 3 ms 860 KB Output is correct
10 Correct 61 ms 6788 KB Output is correct
11 Correct 65 ms 6604 KB Output is correct
12 Correct 61 ms 6848 KB Output is correct
13 Correct 60 ms 6628 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 604 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 0 ms 348 KB Output is correct
4 Correct 0 ms 348 KB Output is correct
5 Correct 0 ms 348 KB Output is correct
6 Correct 3 ms 792 KB Output is correct
7 Correct 57 ms 6580 KB Output is correct
8 Correct 2 ms 348 KB Output is correct
9 Correct 3 ms 860 KB Output is correct
10 Correct 61 ms 6788 KB Output is correct
11 Correct 65 ms 6604 KB Output is correct
12 Correct 61 ms 6848 KB Output is correct
13 Correct 60 ms 6628 KB Output is correct
14 Correct 102 ms 12976 KB Output is correct
15 Correct 654 ms 84276 KB Output is correct
16 Correct 107 ms 13192 KB Output is correct
17 Correct 641 ms 84280 KB Output is correct
18 Correct 761 ms 83884 KB Output is correct
19 Correct 458 ms 84276 KB Output is correct
20 Correct 585 ms 84168 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 63 ms 5716 KB Output is correct
4 Correct 589 ms 85248 KB Output is correct
5 Correct 643 ms 85020 KB Output is correct
6 Correct 673 ms 84120 KB Output is correct
7 Correct 700 ms 84024 KB Output is correct
8 Correct 653 ms 84024 KB Output is correct
9 Correct 574 ms 85088 KB Output is correct
10 Correct 595 ms 85048 KB Output is correct
11 Correct 678 ms 83280 KB Output is correct
12 Correct 437 ms 83504 KB Output is correct
13 Correct 735 ms 84572 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 348 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 1 ms 348 KB Output is correct
4 Correct 0 ms 348 KB Output is correct
5 Correct 0 ms 348 KB Output is correct
6 Correct 1 ms 520 KB Output is correct
7 Correct 12 ms 1340 KB Output is correct
8 Correct 10 ms 1292 KB Output is correct
9 Correct 12 ms 1372 KB Output is correct
10 Correct 10 ms 1488 KB Output is correct
11 Correct 12 ms 1372 KB Output is correct
12 Correct 11 ms 1372 KB Output is correct
13 Correct 9 ms 1372 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 0 ms 348 KB Output is correct
4 Correct 0 ms 348 KB Output is correct
5 Correct 2 ms 604 KB Output is correct
6 Correct 596 ms 82844 KB Output is correct
7 Correct 630 ms 83000 KB Output is correct
8 Correct 630 ms 83008 KB Output is correct
9 Correct 638 ms 83256 KB Output is correct
10 Correct 533 ms 84048 KB Output is correct
11 Correct 610 ms 83768 KB Output is correct
12 Correct 508 ms 83240 KB Output is correct
13 Correct 555 ms 83764 KB Output is correct
14 Correct 622 ms 82944 KB Output is correct
15 Correct 654 ms 83012 KB Output is correct
16 Correct 532 ms 84036 KB Output is correct
17 Correct 551 ms 83140 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 0 ms 348 KB Output is correct
4 Correct 0 ms 348 KB Output is correct
5 Correct 0 ms 348 KB Output is correct
6 Correct 38 ms 4028 KB Output is correct
7 Correct 105 ms 13392 KB Output is correct
8 Correct 497 ms 84112 KB Output is correct
9 Correct 524 ms 84064 KB Output is correct
10 Correct 551 ms 84496 KB Output is correct
11 Correct 590 ms 84964 KB Output is correct
12 Correct 601 ms 83952 KB Output is correct
13 Correct 694 ms 83280 KB Output is correct
14 Correct 392 ms 83496 KB Output is correct
15 Correct 0 ms 604 KB Output is correct
16 Correct 0 ms 348 KB Output is correct
17 Correct 0 ms 348 KB Output is correct
18 Correct 0 ms 348 KB Output is correct
19 Correct 0 ms 348 KB Output is correct
20 Correct 3 ms 792 KB Output is correct
21 Correct 57 ms 6580 KB Output is correct
22 Correct 2 ms 348 KB Output is correct
23 Correct 3 ms 860 KB Output is correct
24 Correct 61 ms 6788 KB Output is correct
25 Correct 65 ms 6604 KB Output is correct
26 Correct 61 ms 6848 KB Output is correct
27 Correct 60 ms 6628 KB Output is correct
28 Correct 102 ms 12976 KB Output is correct
29 Correct 654 ms 84276 KB Output is correct
30 Correct 107 ms 13192 KB Output is correct
31 Correct 641 ms 84280 KB Output is correct
32 Correct 761 ms 83884 KB Output is correct
33 Correct 458 ms 84276 KB Output is correct
34 Correct 585 ms 84168 KB Output is correct
35 Correct 0 ms 348 KB Output is correct
36 Correct 0 ms 348 KB Output is correct
37 Correct 63 ms 5716 KB Output is correct
38 Correct 589 ms 85248 KB Output is correct
39 Correct 643 ms 85020 KB Output is correct
40 Correct 673 ms 84120 KB Output is correct
41 Correct 700 ms 84024 KB Output is correct
42 Correct 653 ms 84024 KB Output is correct
43 Correct 574 ms 85088 KB Output is correct
44 Correct 595 ms 85048 KB Output is correct
45 Correct 678 ms 83280 KB Output is correct
46 Correct 437 ms 83504 KB Output is correct
47 Correct 735 ms 84572 KB Output is correct
48 Correct 1 ms 348 KB Output is correct
49 Correct 0 ms 348 KB Output is correct
50 Correct 1 ms 348 KB Output is correct
51 Correct 0 ms 348 KB Output is correct
52 Correct 0 ms 348 KB Output is correct
53 Correct 1 ms 520 KB Output is correct
54 Correct 12 ms 1340 KB Output is correct
55 Correct 10 ms 1292 KB Output is correct
56 Correct 12 ms 1372 KB Output is correct
57 Correct 10 ms 1488 KB Output is correct
58 Correct 12 ms 1372 KB Output is correct
59 Correct 11 ms 1372 KB Output is correct
60 Correct 9 ms 1372 KB Output is correct
61 Correct 56 ms 5456 KB Output is correct
62 Correct 110 ms 13140 KB Output is correct
63 Correct 521 ms 84056 KB Output is correct
64 Correct 597 ms 83764 KB Output is correct
65 Correct 694 ms 83764 KB Output is correct
66 Correct 703 ms 83872 KB Output is correct
67 Correct 653 ms 84024 KB Output is correct
68 Correct 623 ms 85152 KB Output is correct
69 Correct 672 ms 85140 KB Output is correct
70 Correct 597 ms 85420 KB Output is correct
71 Correct 615 ms 84024 KB Output is correct
72 Correct 683 ms 83820 KB Output is correct
73 Correct 702 ms 83880 KB Output is correct
74 Correct 525 ms 83736 KB Output is correct
75 Correct 587 ms 84040 KB Output is correct