답안 #936428

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
936428 2024-03-01T19:15:38 Z EJIC_B_KEDAX 식물 비교 (IOI20_plants) C++17
75 / 100
2475 ms 293292 KB
#include <bits/stdc++.h>
#include "plants.h"

#define x first
#define y second

using ll = long long;
 
using namespace std;
 
const int LG = 19, N = 1 << LG;
int st1[2 * N], st2[2 * N], lz1[2 * N], lz2[2 * N], timer = 1, fndl[2 * N], fndl2[2 * N], used3[N], level[N], kk, nn;
pair<int, int> fnd[2 * N], binupl[LG][N];
pair<int, ll> binupr[LG][N], fnd2[2 * N];
vector<pair<int, int>> mst[2 * N];



void push(int i, int st[], int lz[]) {
	if (lz[i] != -1) {
		st[2 * i + 1] = lz[i];
		st[2 * i + 2] = lz[i];
		lz[2 * i + 1] = lz[i];
		lz[2 * i + 2] = lz[i];
		lz[i] = -1;
	}
}

void set_seg(int l, int r, int x, int st[], int lz[], int l1 = 0, int r1 = N - 1, int i = 0) {
	if (l1 >= l && r1 <= r) {
		st[i] = x;
		lz[i] = x;
		return;
	}
	if (l1 > r || r1 < l) {
		return;
	}
	push(i, st, lz);
	set_seg(l, r, x, st, lz, l1, (l1 + r1) / 2, 2 * i + 1);
	set_seg(l, r, x, st, lz, (l1 + r1) / 2 + 1, r1, 2 * i + 2);
	st[i] = min(st[2 * i + 1], st[2 * i + 2]);
}

int get(int ind, int st[], int lz[], int l1 = 0, int r1 = N - 1, int i = 0) {
	if (l1 == ind && r1 == ind) {
		return st[i];
	}
	if (l1 > ind || r1 < ind) {
		return INT32_MAX;
	}
	push(i, st, lz);
	return min(get(ind, st, lz, l1, (l1 + r1) / 2, 2 * i + 1), get(ind, st, lz, (l1 + r1) / 2 + 1, r1, 2 * i + 2));
}

void push(int i) {
	fnd[2 * i + 1].x += fndl[i];
	fnd[2 * i + 2].x += fndl[i];
	fndl[2 * i + 1] += fndl[i];
	fndl[2 * i + 2] += fndl[i];
	fndl[i] = 0;
}

void push1(int i) {
	fnd2[2 * i + 1].x += fndl2[i];
	fnd2[2 * i + 2].x += fndl2[i];
	fndl2[2 * i + 1] += fndl2[i];
	fndl2[2 * i + 2] += fndl2[i];
	fndl2[i] = 0;
}

void add_seg(int l, int r, int x, int l1 = 0, int r1 = N - 1, int i = 0) {
	if (l1 >= l && r1 <= r) {
		fnd[i].x += x;
		fndl[i] += x;
		return;
	}
	if (l1 > r || r1 < l) {
		return;
	}
	push(i);
	add_seg(l, r, x, l1, (l1 + r1) / 2, 2 * i + 1);
	add_seg(l, r, x, (l1 + r1) / 2 + 1, r1, 2 * i + 2);
	fnd[i] = min(fnd[2 * i + 1], fnd[2 * i + 2]);
}

pair<int, int> get_min(int l, int r, int l1 = 0, int r1 = N - 1, int i = 0) {
	if (l1 >= l && r1 <= r) {
		return fnd[i];
	}
	if (l1 > r || r1 < l) {
		return {INT32_MAX, -1};
	}
	push(i);
	return min(get_min(l, r, l1, (l1 + r1) / 2, 2 * i + 1), get_min(l, r, (l1 + r1) / 2 + 1, r1, 2 * i + 2));
}

void add_seg1(int l, int r, int x, int l1 = 0, int r1 = N - 1, int i = 0) {
	if (l1 >= l && r1 <= r) {
		fnd2[i].x += x;
		fndl2[i] += x;
		return;
	}
	if (l1 > r || r1 < l) {
		return;
	}
	push1(i);
	add_seg1(l, r, x, l1, (l1 + r1) / 2, 2 * i + 1);
	add_seg1(l, r, x, (l1 + r1) / 2 + 1, r1, 2 * i + 2);
	fnd2[i] = min(fnd2[2 * i + 1], fnd2[2 * i + 2]);
}

pair<int, int> get_min1(int l, int r, int l1 = 0, int r1 = N - 1, int i = 0) {
	if (l1 >= l && r1 <= r) {
		return fnd2[i];
	}
	if (l1 > r || r1 < l) {
		return {INT32_MAX, -1};
	}
	push1(i);
	return min(get_min1(l, r, l1, (l1 + r1) / 2, 2 * i + 1), get_min1(l, r, (l1 + r1) / 2 + 1, r1, 2 * i + 2));
}

pair<int, int> find_max(int i, int v) {
	int l = -1, r = mst[i].size();
	while (r - l > 1) {
		int m = (r + l) / 2;
		if (mst[i][m].x >= v) {
			r = m;
		} else {
			l = m;
		}
	}
	return l == -1 ? make_pair(-1, N) : mst[i][l];
}

pair<int, int> get_max(int l, int r, int v) {
	l += N - 1;
	r += N - 1;
	pair<int, int> res = {-1, -1};
	while (l <= r) {
		if (~l & 1) {
			res = max(res, find_max(l++, v));
		}
		if (r & 1) {
			res = max(res, find_max(r--, v));
		}
		l = (l - 1) / 2;
		r = (r - 1) / 2;
	}
	return res;
}

void mrg(int to, int a, int b) {
	mst[to].resize(mst[a].size() + mst[b].size());
	std::merge(mst[a].begin(), mst[a].end(), mst[b].begin(), mst[b].end(), mst[to].begin());
}

void init(int k, vector<int> r) {
	kk = k;
    int n = r.size();
    nn = n;
    int ok = 0;
    for (int i = 0; i < 2 * N; i++) {
    	st1[i] = -1;
    	st2[i] = -1;
    	lz1[i] = -1;
    	lz2[i] = -1;
    }
    for (int i = 0; i < N; i++) {
    	fnd[i + N - 1].y = i;
    	fnd2[i + N - 1].y = i;
    	level[i] = n;
    }
    for (int i = 0; i < n; i++) {
    	add_seg(i, i, r[i]);
    	add_seg1(i, i, r[i]);
		if (r[i] == 0) {
			used3[i] = 1;
			if (i + k > n) {
				add_seg(i + 1, n - 1, 1);
				add_seg(0, i + k - n - 1, 1);
			} else {
				add_seg(i + 1, i + k - 1, 1);
			}
		}
    }
    while (ok < n) {
    	auto [value, i] = get_min(0, n - 1);
    	// cout << i << '\n';
    	// for (int i = 0; i < n; i++) {
    	// 	cout << get_min(i, i).x << ' ';
    	// }
    	// cout << '\n';
    	if (value) {
    		// cout << value << ' ' << ok << '\n';
    		exit(1);
    	}
    	int tmp1 = get(i, st1, lz1), tmp2 = get(i, st2, lz2);
    	if (tmp1 != -1) {
    		level[i] = min(level[i], level[tmp1] - 1);
    	}
    	if (tmp2 != -1) {
    		level[i] = min(level[i], level[tmp2] - 1);
    	}
    	vector<int> z;
        if (i + k - 1 < n) {
    		set_seg(i + 1, i + k - 1, i, st2, lz2);
    		add_seg(i + 1, i + k - 1, -1);
    	} else {
    		set_seg(i + 1, n - 1, i, st2, lz2);
    		set_seg(0, i + k - 1 - n, i, st2, lz2);
    		add_seg(i + 1, n - 1, -1);
    		add_seg(0, i + k - 1 - n, -1);
    	}
    	if (i >= k - 1) {
    		add_seg(i - k + 1, i - 1, -1);
    		add_seg1(i - k + 1, i - 1, -1);
    		int left = i - k + 1;
    		while (left <= i - 1 && !get_min1(left, i - 1).x) {
    			z.push_back(get_min1(left, i - 1).y);
    			assert(left <= z.back());
    			left = z.back() + 1;
    		}
    		set_seg(i - k + 1, i - 1, i, st1, lz1);
    	} else {
    		add_seg(0, i - 1, -1);
    		add_seg1(0, i - 1, -1);
    		set_seg(0, i - 1, i, st1, lz1);
    		add_seg(n + 1 - k + i, n - 1, -1);
    		add_seg1(n + 1 - k + i, n - 1, -1);
    		set_seg(n + 1 - k + i, n - 1, i, st1, lz1);
    		int left = 0;
    		while (left <= i - 1 && !get_min1(left, i - 1).x) {
    			z.push_back(get_min1(left, i - 1).y);
    			assert(left <= z.back());
    			left = z.back() + 1;
    		}
    		left = n + 1 - k + i;
    		while (left <= n - 1 && !get_min1(left, n - 1).x) {
    			z.push_back(get_min1(left, n - 1).y);
    			assert(left <= z.back());
    			left = z.back() + 1;
    		}
    	}
    	for (int j : z) {
    		if (!used3[j]) {
				if (j + k > n) {
					add_seg(j + 1, n - 1, 1);
					add_seg(0, j + k - n - 1, 1);
				} else {
					add_seg(j + 1, j + k - 1, 1);
				}
				used3[j] = 1;
			}
		}
        add_seg(i, i, INT32_MAX / 2);
        add_seg1(i, i, INT32_MAX / 2);
    	ok++;
    }
    // for (int i = 0; i < n; i++) {
    // 	cout << level[i] << ' ';
    // }
    // cout << '\n';
    // for (int i = 0; i < n; i++) {
    // 	mst[N - 1 + i].emplace_back(level[i], i);
    // }
    // for (int i = N - 2; i >= 0; i--) {
    // 	mrg(i, 2 * i + 1, 2 * i + 2);
    // }
    set<pair<int, int>> st1;
    set<pair<int, int>> st2;
    for (int i = n - k + 1; i < n; i++) {
    	st1.emplace(-level[i], i);
    }
    for (int i = 1; i < k; i++) {
    	st2.emplace(-level[i], i);
    }
    for (int i = 0; i < n; i++) {
    	auto lb1 = st1.lower_bound({-level[i], N});
    	if (lb1 == st1.end()) {
    		binupl[0][i].x = i;
    	} else {
    		binupl[0][i].x = (*lb1).y;
    	}
    	st1.erase({-level[(i - k + 1 + n) % n], (i - k + 1 + n) % n});
    	st1.emplace(-level[i], i);
    	// if (i >= k - 1) {
    	// 	binupl[0][i].x = get_max(i - k + 1, i - 1, level[i]).y;
    	// } else {
    	// 	binupl[0][i].x = max(get_max(0, i - 1, level[i]), get_max(n + i - k + 1, n - 1, level[i])).y;
    	// }
    	// if (binupl[0][i].x == N) {
    	// 	binupl[0][i].x = i;
    	// }
    	binupl[0][i].y = i - binupl[0][i].x;
    	if (binupl[0][i].y < 0) {
    		binupl[0][i].y += n;
    	}
    	auto lb2 = st2.lower_bound({-level[i], N});
    	if (lb2 == st2.end()) {
    		binupr[0][i].x = i;
    	} else {
    		binupr[0][i].x = (*lb2).y;
    	}
    	st2.erase({-level[i + 1], i + 1});
    	st2.emplace(-level[(i + k) % n], (i + k) % n);
    	// if (i + k - 1 < n) {
    	// 	binupr[0][i].x = get_max(i + 1, i + k - 1, level[i]).y;
    	// } else {
    	// 	binupr[0][i].x = max(get_max(i + 1, n - 1, level[i]), get_max(0, i + k - 1 - n, level[i])).y;
    	// }
    	// if (binupr[0][i].x == N) {
    	// 	binupr[0][i].x = i;
    	// }
    	binupr[0][i].y = binupr[0][i].x - i;
    	if (binupr[0][i].y < 0) {
    		binupr[0][i].y += n;
    	}
    }
    for (int l = 1; l < LG; l++) {
    	for (int i = 0; i < n; i++) {
    		binupl[l][i].x = binupl[l - 1][binupl[l - 1][i].x].x;
    		binupr[l][i].x = binupr[l - 1][binupr[l - 1][i].x].x;
    		binupl[l][i].y = binupl[l - 1][binupl[l - 1][i].x].y + binupl[l - 1][i].y;
    		binupr[l][i].y = binupr[l - 1][binupr[l - 1][i].x].y + binupr[l - 1][i].y;
    	}
    }
    for (int i = 0; i < n; i++) {
    	for (int l = 0; l < 1; l++) {
    		assert(binupl[l][i].y >= 0);
    		assert(binupr[l][i].y >= 0);
    	}
    }
}

bool try_compare(int x, int y) {
	ll dist = x - y;
	int nw = x;
	if (dist < 0) {
		dist += nn;
	}
	dist -= kk - 1;
	if (dist <= 0) {
		// cout << "! " << nw << '\n';
		return true;
	} 
	for (int i = LG - 1; i >= 0; i--) {
		if (binupl[i][nw].y < dist) {
			dist -= binupl[i][nw].y;
			nw = binupl[i][nw].x;
		}
	}
	assert(dist > 0);
	dist -= binupl[0][nw].y;
	nw = binupl[0][nw].x;
	if (level[nw] >= level[y] && dist <= 0) {
		// cout << "!! " << nw << '\n';
		return true;
	}
	dist = y - x, nw = x;
	if (dist < 0) {
		dist += nn;
	}
	dist -= kk - 1;
	if (dist <= 0) {
		// cout << "!!! " << nw << '\n';
		return true;
	}
	for (int i = LG - 1; i >= 0; i--) {
		if (binupr[i][nw].y < dist) {
			dist -= binupr[i][nw].y;
			nw = binupr[i][nw].x;
		}
	}
	assert(dist > 0);
	dist -= binupr[0][nw].y;
	nw = binupr[0][nw].x;
	if (level[nw] >= level[y] && dist <= 0) {
		// cout << "!!!! " << nw << '\n';
		return true;
	}
	return false;
}
 
int compare_plants(int x, int y) {
	if (try_compare(x, y) && level[x] > level[y]) {
		return 1;
	}
	if (try_compare(y, x) && level[y] > level[x]) {
		return -1;
	}
	// if (level[x] > level[y]) {
	// 	return 1;
	// }
	// if (level[y] > level[x]) {
	// 	return -1;
	// }
	return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 22 ms 150104 KB Output is correct
2 Correct 23 ms 150276 KB Output is correct
3 Correct 23 ms 150104 KB Output is correct
4 Correct 21 ms 150108 KB Output is correct
5 Correct 21 ms 150152 KB Output is correct
6 Correct 145 ms 152896 KB Output is correct
7 Correct 396 ms 192044 KB Output is correct
8 Correct 1617 ms 274516 KB Output is correct
9 Correct 1618 ms 274512 KB Output is correct
10 Correct 1557 ms 274380 KB Output is correct
11 Correct 1506 ms 274580 KB Output is correct
12 Correct 1540 ms 274376 KB Output is correct
13 Correct 1322 ms 274904 KB Output is correct
14 Correct 1464 ms 274408 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 23 ms 150100 KB Output is correct
2 Correct 21 ms 150096 KB Output is correct
3 Correct 22 ms 150108 KB Output is correct
4 Correct 21 ms 150204 KB Output is correct
5 Correct 22 ms 150360 KB Output is correct
6 Correct 30 ms 150352 KB Output is correct
7 Correct 110 ms 153428 KB Output is correct
8 Correct 24 ms 150368 KB Output is correct
9 Correct 31 ms 150284 KB Output is correct
10 Correct 113 ms 153416 KB Output is correct
11 Correct 103 ms 153172 KB Output is correct
12 Correct 118 ms 153316 KB Output is correct
13 Correct 98 ms 153428 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 23 ms 150100 KB Output is correct
2 Correct 21 ms 150096 KB Output is correct
3 Correct 22 ms 150108 KB Output is correct
4 Correct 21 ms 150204 KB Output is correct
5 Correct 22 ms 150360 KB Output is correct
6 Correct 30 ms 150352 KB Output is correct
7 Correct 110 ms 153428 KB Output is correct
8 Correct 24 ms 150368 KB Output is correct
9 Correct 31 ms 150284 KB Output is correct
10 Correct 113 ms 153416 KB Output is correct
11 Correct 103 ms 153172 KB Output is correct
12 Correct 118 ms 153316 KB Output is correct
13 Correct 98 ms 153428 KB Output is correct
14 Correct 233 ms 193108 KB Output is correct
15 Correct 2414 ms 286012 KB Output is correct
16 Correct 247 ms 193104 KB Output is correct
17 Correct 2475 ms 286132 KB Output is correct
18 Correct 1315 ms 284080 KB Output is correct
19 Correct 1360 ms 284132 KB Output is correct
20 Correct 2143 ms 293292 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 22 ms 150108 KB Output is correct
2 Correct 22 ms 150108 KB Output is correct
3 Correct 193 ms 152912 KB Output is correct
4 Correct 1488 ms 274516 KB Output is correct
5 Correct 1625 ms 274496 KB Output is correct
6 Correct 1908 ms 274496 KB Output is correct
7 Correct 2071 ms 275632 KB Output is correct
8 Correct 2183 ms 283120 KB Output is correct
9 Correct 1583 ms 274492 KB Output is correct
10 Correct 1513 ms 274508 KB Output is correct
11 Correct 1280 ms 274612 KB Output is correct
12 Correct 1614 ms 274516 KB Output is correct
13 Correct 1488 ms 280296 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 21 ms 150108 KB Output is correct
2 Correct 22 ms 150068 KB Output is correct
3 Correct 20 ms 150364 KB Output is correct
4 Correct 21 ms 150104 KB Output is correct
5 Correct 21 ms 150108 KB Output is correct
6 Correct 30 ms 150364 KB Output is correct
7 Correct 50 ms 150868 KB Output is correct
8 Correct 42 ms 150868 KB Output is correct
9 Correct 47 ms 150812 KB Output is correct
10 Correct 42 ms 150868 KB Output is correct
11 Correct 67 ms 150864 KB Output is correct
12 Correct 61 ms 150808 KB Output is correct
13 Correct 33 ms 150900 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 21 ms 150104 KB Output is correct
2 Correct 21 ms 150180 KB Output is correct
3 Correct 22 ms 150104 KB Output is correct
4 Correct 22 ms 150156 KB Output is correct
5 Correct 31 ms 150104 KB Output is correct
6 Correct 1434 ms 274516 KB Output is correct
7 Correct 1591 ms 274756 KB Output is correct
8 Correct 1863 ms 275520 KB Output is correct
9 Correct 2150 ms 282940 KB Output is correct
10 Correct 1453 ms 274496 KB Output is correct
11 Correct 1537 ms 281940 KB Output is correct
12 Correct 1191 ms 274496 KB Output is correct
13 Correct 1411 ms 274536 KB Output is correct
14 Correct 1603 ms 274680 KB Output is correct
15 Correct 1884 ms 275524 KB Output is correct
16 Correct 1120 ms 274512 KB Output is correct
17 Correct 1283 ms 274640 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 22 ms 150104 KB Output is correct
2 Correct 23 ms 150276 KB Output is correct
3 Correct 23 ms 150104 KB Output is correct
4 Correct 21 ms 150108 KB Output is correct
5 Correct 21 ms 150152 KB Output is correct
6 Correct 145 ms 152896 KB Output is correct
7 Correct 396 ms 192044 KB Output is correct
8 Correct 1617 ms 274516 KB Output is correct
9 Correct 1618 ms 274512 KB Output is correct
10 Correct 1557 ms 274380 KB Output is correct
11 Correct 1506 ms 274580 KB Output is correct
12 Correct 1540 ms 274376 KB Output is correct
13 Correct 1322 ms 274904 KB Output is correct
14 Correct 1464 ms 274408 KB Output is correct
15 Correct 23 ms 150100 KB Output is correct
16 Correct 21 ms 150096 KB Output is correct
17 Correct 22 ms 150108 KB Output is correct
18 Correct 21 ms 150204 KB Output is correct
19 Correct 22 ms 150360 KB Output is correct
20 Correct 30 ms 150352 KB Output is correct
21 Correct 110 ms 153428 KB Output is correct
22 Correct 24 ms 150368 KB Output is correct
23 Correct 31 ms 150284 KB Output is correct
24 Correct 113 ms 153416 KB Output is correct
25 Correct 103 ms 153172 KB Output is correct
26 Correct 118 ms 153316 KB Output is correct
27 Correct 98 ms 153428 KB Output is correct
28 Correct 233 ms 193108 KB Output is correct
29 Correct 2414 ms 286012 KB Output is correct
30 Correct 247 ms 193104 KB Output is correct
31 Correct 2475 ms 286132 KB Output is correct
32 Correct 1315 ms 284080 KB Output is correct
33 Correct 1360 ms 284132 KB Output is correct
34 Correct 2143 ms 293292 KB Output is correct
35 Correct 22 ms 150108 KB Output is correct
36 Correct 22 ms 150108 KB Output is correct
37 Correct 193 ms 152912 KB Output is correct
38 Correct 1488 ms 274516 KB Output is correct
39 Correct 1625 ms 274496 KB Output is correct
40 Correct 1908 ms 274496 KB Output is correct
41 Correct 2071 ms 275632 KB Output is correct
42 Correct 2183 ms 283120 KB Output is correct
43 Correct 1583 ms 274492 KB Output is correct
44 Correct 1513 ms 274508 KB Output is correct
45 Correct 1280 ms 274612 KB Output is correct
46 Correct 1614 ms 274516 KB Output is correct
47 Correct 1488 ms 280296 KB Output is correct
48 Correct 21 ms 150108 KB Output is correct
49 Correct 22 ms 150068 KB Output is correct
50 Correct 20 ms 150364 KB Output is correct
51 Correct 21 ms 150104 KB Output is correct
52 Correct 21 ms 150108 KB Output is correct
53 Correct 30 ms 150364 KB Output is correct
54 Correct 50 ms 150868 KB Output is correct
55 Correct 42 ms 150868 KB Output is correct
56 Correct 47 ms 150812 KB Output is correct
57 Correct 42 ms 150868 KB Output is correct
58 Correct 67 ms 150864 KB Output is correct
59 Correct 61 ms 150808 KB Output is correct
60 Correct 33 ms 150900 KB Output is correct
61 Correct 221 ms 153164 KB Output is correct
62 Correct 631 ms 192020 KB Output is correct
63 Correct 2238 ms 274516 KB Output is correct
64 Correct 1452 ms 274500 KB Output is correct
65 Correct 1799 ms 274600 KB Output is correct
66 Correct 2137 ms 275516 KB Output is correct
67 Incorrect 2210 ms 283200 KB Output isn't correct
68 Halted 0 ms 0 KB -