답안 #936426

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
936426 2024-03-01T19:11:13 Z EJIC_B_KEDAX 식물 비교 (IOI20_plants) C++17
75 / 100
2482 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;
    	}
    }
}

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 32 ms 150096 KB Output is correct
2 Correct 21 ms 150104 KB Output is correct
3 Correct 21 ms 150108 KB Output is correct
4 Correct 21 ms 150104 KB Output is correct
5 Correct 23 ms 150100 KB Output is correct
6 Correct 278 ms 152916 KB Output is correct
7 Correct 471 ms 192084 KB Output is correct
8 Correct 1711 ms 274492 KB Output is correct
9 Correct 1614 ms 274512 KB Output is correct
10 Correct 1500 ms 274484 KB Output is correct
11 Correct 1533 ms 274524 KB Output is correct
12 Correct 1511 ms 274768 KB Output is correct
13 Correct 1291 ms 274516 KB Output is correct
14 Correct 1421 ms 274544 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 20 ms 150164 KB Output is correct
4 Correct 21 ms 150072 KB Output is correct
5 Correct 22 ms 150232 KB Output is correct
6 Correct 29 ms 150352 KB Output is correct
7 Correct 111 ms 153292 KB Output is correct
8 Correct 25 ms 150364 KB Output is correct
9 Correct 34 ms 150356 KB Output is correct
10 Correct 110 ms 153552 KB Output is correct
11 Correct 108 ms 153160 KB Output is correct
12 Correct 121 ms 153428 KB Output is correct
13 Correct 100 ms 153564 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 20 ms 150164 KB Output is correct
4 Correct 21 ms 150072 KB Output is correct
5 Correct 22 ms 150232 KB Output is correct
6 Correct 29 ms 150352 KB Output is correct
7 Correct 111 ms 153292 KB Output is correct
8 Correct 25 ms 150364 KB Output is correct
9 Correct 34 ms 150356 KB Output is correct
10 Correct 110 ms 153552 KB Output is correct
11 Correct 108 ms 153160 KB Output is correct
12 Correct 121 ms 153428 KB Output is correct
13 Correct 100 ms 153564 KB Output is correct
14 Correct 245 ms 193104 KB Output is correct
15 Correct 2364 ms 286288 KB Output is correct
16 Correct 247 ms 193108 KB Output is correct
17 Correct 2482 ms 286008 KB Output is correct
18 Correct 1305 ms 283904 KB Output is correct
19 Correct 1407 ms 284092 KB Output is correct
20 Correct 2197 ms 293292 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 23 ms 150108 KB Output is correct
2 Correct 23 ms 150108 KB Output is correct
3 Correct 172 ms 152908 KB Output is correct
4 Correct 1441 ms 274700 KB Output is correct
5 Correct 1760 ms 274508 KB Output is correct
6 Correct 1844 ms 274492 KB Output is correct
7 Correct 2017 ms 275536 KB Output is correct
8 Correct 2306 ms 282960 KB Output is correct
9 Correct 1580 ms 274628 KB Output is correct
10 Correct 1529 ms 274492 KB Output is correct
11 Correct 1358 ms 274496 KB Output is correct
12 Correct 1636 ms 275256 KB Output is correct
13 Correct 1561 ms 280152 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 21 ms 150104 KB Output is correct
2 Correct 21 ms 150108 KB Output is correct
3 Correct 21 ms 150296 KB Output is correct
4 Correct 22 ms 150108 KB Output is correct
5 Correct 22 ms 150108 KB Output is correct
6 Correct 25 ms 150360 KB Output is correct
7 Correct 60 ms 150856 KB Output is correct
8 Correct 37 ms 150872 KB Output is correct
9 Correct 47 ms 150772 KB Output is correct
10 Correct 39 ms 150868 KB Output is correct
11 Correct 59 ms 150896 KB Output is correct
12 Correct 50 ms 150868 KB Output is correct
13 Correct 33 ms 150816 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 24 ms 150104 KB Output is correct
2 Correct 20 ms 150108 KB Output is correct
3 Correct 21 ms 150360 KB Output is correct
4 Correct 22 ms 150108 KB Output is correct
5 Correct 31 ms 150096 KB Output is correct
6 Correct 1330 ms 274496 KB Output is correct
7 Correct 1575 ms 274588 KB Output is correct
8 Correct 1861 ms 275520 KB Output is correct
9 Correct 2203 ms 282948 KB Output is correct
10 Correct 1386 ms 274500 KB Output is correct
11 Correct 1541 ms 282408 KB Output is correct
12 Correct 1225 ms 274492 KB Output is correct
13 Correct 1445 ms 274516 KB Output is correct
14 Correct 1604 ms 274676 KB Output is correct
15 Correct 1999 ms 275536 KB Output is correct
16 Correct 1088 ms 274604 KB Output is correct
17 Correct 1289 ms 274500 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 32 ms 150096 KB Output is correct
2 Correct 21 ms 150104 KB Output is correct
3 Correct 21 ms 150108 KB Output is correct
4 Correct 21 ms 150104 KB Output is correct
5 Correct 23 ms 150100 KB Output is correct
6 Correct 278 ms 152916 KB Output is correct
7 Correct 471 ms 192084 KB Output is correct
8 Correct 1711 ms 274492 KB Output is correct
9 Correct 1614 ms 274512 KB Output is correct
10 Correct 1500 ms 274484 KB Output is correct
11 Correct 1533 ms 274524 KB Output is correct
12 Correct 1511 ms 274768 KB Output is correct
13 Correct 1291 ms 274516 KB Output is correct
14 Correct 1421 ms 274544 KB Output is correct
15 Correct 21 ms 150108 KB Output is correct
16 Correct 21 ms 150108 KB Output is correct
17 Correct 20 ms 150164 KB Output is correct
18 Correct 21 ms 150072 KB Output is correct
19 Correct 22 ms 150232 KB Output is correct
20 Correct 29 ms 150352 KB Output is correct
21 Correct 111 ms 153292 KB Output is correct
22 Correct 25 ms 150364 KB Output is correct
23 Correct 34 ms 150356 KB Output is correct
24 Correct 110 ms 153552 KB Output is correct
25 Correct 108 ms 153160 KB Output is correct
26 Correct 121 ms 153428 KB Output is correct
27 Correct 100 ms 153564 KB Output is correct
28 Correct 245 ms 193104 KB Output is correct
29 Correct 2364 ms 286288 KB Output is correct
30 Correct 247 ms 193108 KB Output is correct
31 Correct 2482 ms 286008 KB Output is correct
32 Correct 1305 ms 283904 KB Output is correct
33 Correct 1407 ms 284092 KB Output is correct
34 Correct 2197 ms 293292 KB Output is correct
35 Correct 23 ms 150108 KB Output is correct
36 Correct 23 ms 150108 KB Output is correct
37 Correct 172 ms 152908 KB Output is correct
38 Correct 1441 ms 274700 KB Output is correct
39 Correct 1760 ms 274508 KB Output is correct
40 Correct 1844 ms 274492 KB Output is correct
41 Correct 2017 ms 275536 KB Output is correct
42 Correct 2306 ms 282960 KB Output is correct
43 Correct 1580 ms 274628 KB Output is correct
44 Correct 1529 ms 274492 KB Output is correct
45 Correct 1358 ms 274496 KB Output is correct
46 Correct 1636 ms 275256 KB Output is correct
47 Correct 1561 ms 280152 KB Output is correct
48 Correct 21 ms 150104 KB Output is correct
49 Correct 21 ms 150108 KB Output is correct
50 Correct 21 ms 150296 KB Output is correct
51 Correct 22 ms 150108 KB Output is correct
52 Correct 22 ms 150108 KB Output is correct
53 Correct 25 ms 150360 KB Output is correct
54 Correct 60 ms 150856 KB Output is correct
55 Correct 37 ms 150872 KB Output is correct
56 Correct 47 ms 150772 KB Output is correct
57 Correct 39 ms 150868 KB Output is correct
58 Correct 59 ms 150896 KB Output is correct
59 Correct 50 ms 150868 KB Output is correct
60 Correct 33 ms 150816 KB Output is correct
61 Correct 245 ms 153172 KB Output is correct
62 Correct 496 ms 192040 KB Output is correct
63 Correct 2156 ms 274640 KB Output is correct
64 Correct 1384 ms 274520 KB Output is correct
65 Correct 1824 ms 274492 KB Output is correct
66 Correct 1971 ms 275536 KB Output is correct
67 Incorrect 2139 ms 282940 KB Output isn't correct
68 Halted 0 ms 0 KB -