답안 #936429

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
936429 2024-03-01T19:17:16 Z EJIC_B_KEDAX 식물 비교 (IOI20_plants) C++17
75 / 100
2438 ms 293508 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);
    		assert(binupl[l][i].x >= 0);
    		assert(binupr[l][i].x >= 0);
    		assert(binupl[l][i].x < n);
    		assert(binupr[l][i].x < n);
    	}
    }
}

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 40 ms 150128 KB Output is correct
2 Correct 23 ms 150104 KB Output is correct
3 Correct 22 ms 150360 KB Output is correct
4 Correct 21 ms 150108 KB Output is correct
5 Correct 21 ms 150056 KB Output is correct
6 Correct 303 ms 152916 KB Output is correct
7 Correct 517 ms 192080 KB Output is correct
8 Correct 1637 ms 274576 KB Output is correct
9 Correct 1616 ms 274596 KB Output is correct
10 Correct 1507 ms 274516 KB Output is correct
11 Correct 1501 ms 274852 KB Output is correct
12 Correct 1532 ms 274544 KB Output is correct
13 Correct 1276 ms 274496 KB Output is correct
14 Correct 1547 ms 274516 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 22 ms 150240 KB Output is correct
2 Correct 21 ms 150176 KB Output is correct
3 Correct 22 ms 150124 KB Output is correct
4 Correct 23 ms 150104 KB Output is correct
5 Correct 23 ms 150108 KB Output is correct
6 Correct 30 ms 150360 KB Output is correct
7 Correct 106 ms 153304 KB Output is correct
8 Correct 23 ms 150364 KB Output is correct
9 Correct 34 ms 150364 KB Output is correct
10 Correct 106 ms 153428 KB Output is correct
11 Correct 102 ms 153160 KB Output is correct
12 Correct 117 ms 153316 KB Output is correct
13 Correct 115 ms 153552 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 22 ms 150240 KB Output is correct
2 Correct 21 ms 150176 KB Output is correct
3 Correct 22 ms 150124 KB Output is correct
4 Correct 23 ms 150104 KB Output is correct
5 Correct 23 ms 150108 KB Output is correct
6 Correct 30 ms 150360 KB Output is correct
7 Correct 106 ms 153304 KB Output is correct
8 Correct 23 ms 150364 KB Output is correct
9 Correct 34 ms 150364 KB Output is correct
10 Correct 106 ms 153428 KB Output is correct
11 Correct 102 ms 153160 KB Output is correct
12 Correct 117 ms 153316 KB Output is correct
13 Correct 115 ms 153552 KB Output is correct
14 Correct 245 ms 193088 KB Output is correct
15 Correct 2350 ms 286012 KB Output is correct
16 Correct 310 ms 193100 KB Output is correct
17 Correct 2438 ms 286012 KB Output is correct
18 Correct 1312 ms 283988 KB Output is correct
19 Correct 1430 ms 283976 KB Output is correct
20 Correct 2140 ms 293508 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 21 ms 150108 KB Output is correct
2 Correct 21 ms 150108 KB Output is correct
3 Correct 201 ms 152888 KB Output is correct
4 Correct 1547 ms 274492 KB Output is correct
5 Correct 1688 ms 274628 KB Output is correct
6 Correct 1909 ms 274496 KB Output is correct
7 Correct 2069 ms 275448 KB Output is correct
8 Correct 2279 ms 282952 KB Output is correct
9 Correct 1584 ms 274500 KB Output is correct
10 Correct 1581 ms 274496 KB Output is correct
11 Correct 1351 ms 274516 KB Output is correct
12 Correct 1662 ms 274484 KB Output is correct
13 Correct 1502 ms 280128 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 21 ms 150108 KB Output is correct
2 Correct 24 ms 150108 KB Output is correct
3 Correct 21 ms 150108 KB Output is correct
4 Correct 21 ms 150100 KB Output is correct
5 Correct 22 ms 150108 KB Output is correct
6 Correct 28 ms 150364 KB Output is correct
7 Correct 52 ms 150832 KB Output is correct
8 Correct 43 ms 150864 KB Output is correct
9 Correct 59 ms 150784 KB Output is correct
10 Correct 38 ms 150868 KB Output is correct
11 Correct 52 ms 150864 KB Output is correct
12 Correct 50 ms 150684 KB Output is correct
13 Correct 32 ms 150692 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 22 ms 150104 KB Output is correct
2 Correct 25 ms 150108 KB Output is correct
3 Correct 22 ms 150180 KB Output is correct
4 Correct 21 ms 150108 KB Output is correct
5 Correct 31 ms 150104 KB Output is correct
6 Correct 1487 ms 274672 KB Output is correct
7 Correct 1729 ms 274600 KB Output is correct
8 Correct 2055 ms 171840 KB Output is correct
9 Correct 2294 ms 280392 KB Output is correct
10 Correct 1363 ms 171088 KB Output is correct
11 Correct 1529 ms 178492 KB Output is correct
12 Correct 1192 ms 176448 KB Output is correct
13 Correct 1537 ms 250572 KB Output is correct
14 Correct 1562 ms 171296 KB Output is correct
15 Correct 2009 ms 275444 KB Output is correct
16 Correct 1090 ms 267068 KB Output is correct
17 Correct 1290 ms 267264 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 40 ms 150128 KB Output is correct
2 Correct 23 ms 150104 KB Output is correct
3 Correct 22 ms 150360 KB Output is correct
4 Correct 21 ms 150108 KB Output is correct
5 Correct 21 ms 150056 KB Output is correct
6 Correct 303 ms 152916 KB Output is correct
7 Correct 517 ms 192080 KB Output is correct
8 Correct 1637 ms 274576 KB Output is correct
9 Correct 1616 ms 274596 KB Output is correct
10 Correct 1507 ms 274516 KB Output is correct
11 Correct 1501 ms 274852 KB Output is correct
12 Correct 1532 ms 274544 KB Output is correct
13 Correct 1276 ms 274496 KB Output is correct
14 Correct 1547 ms 274516 KB Output is correct
15 Correct 22 ms 150240 KB Output is correct
16 Correct 21 ms 150176 KB Output is correct
17 Correct 22 ms 150124 KB Output is correct
18 Correct 23 ms 150104 KB Output is correct
19 Correct 23 ms 150108 KB Output is correct
20 Correct 30 ms 150360 KB Output is correct
21 Correct 106 ms 153304 KB Output is correct
22 Correct 23 ms 150364 KB Output is correct
23 Correct 34 ms 150364 KB Output is correct
24 Correct 106 ms 153428 KB Output is correct
25 Correct 102 ms 153160 KB Output is correct
26 Correct 117 ms 153316 KB Output is correct
27 Correct 115 ms 153552 KB Output is correct
28 Correct 245 ms 193088 KB Output is correct
29 Correct 2350 ms 286012 KB Output is correct
30 Correct 310 ms 193100 KB Output is correct
31 Correct 2438 ms 286012 KB Output is correct
32 Correct 1312 ms 283988 KB Output is correct
33 Correct 1430 ms 283976 KB Output is correct
34 Correct 2140 ms 293508 KB Output is correct
35 Correct 21 ms 150108 KB Output is correct
36 Correct 21 ms 150108 KB Output is correct
37 Correct 201 ms 152888 KB Output is correct
38 Correct 1547 ms 274492 KB Output is correct
39 Correct 1688 ms 274628 KB Output is correct
40 Correct 1909 ms 274496 KB Output is correct
41 Correct 2069 ms 275448 KB Output is correct
42 Correct 2279 ms 282952 KB Output is correct
43 Correct 1584 ms 274500 KB Output is correct
44 Correct 1581 ms 274496 KB Output is correct
45 Correct 1351 ms 274516 KB Output is correct
46 Correct 1662 ms 274484 KB Output is correct
47 Correct 1502 ms 280128 KB Output is correct
48 Correct 21 ms 150108 KB Output is correct
49 Correct 24 ms 150108 KB Output is correct
50 Correct 21 ms 150108 KB Output is correct
51 Correct 21 ms 150100 KB Output is correct
52 Correct 22 ms 150108 KB Output is correct
53 Correct 28 ms 150364 KB Output is correct
54 Correct 52 ms 150832 KB Output is correct
55 Correct 43 ms 150864 KB Output is correct
56 Correct 59 ms 150784 KB Output is correct
57 Correct 38 ms 150868 KB Output is correct
58 Correct 52 ms 150864 KB Output is correct
59 Correct 50 ms 150684 KB Output is correct
60 Correct 32 ms 150692 KB Output is correct
61 Correct 258 ms 152916 KB Output is correct
62 Correct 636 ms 192040 KB Output is correct
63 Correct 2235 ms 267076 KB Output is correct
64 Correct 1465 ms 173404 KB Output is correct
65 Correct 1858 ms 269236 KB Output is correct
66 Correct 2137 ms 275516 KB Output is correct
67 Incorrect 2229 ms 277404 KB Output isn't correct
68 Halted 0 ms 0 KB -