이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include "plants.h"
using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set = tree <T, null_type, less <T>, rb_tree_tag, tree_order_statistics_node_update>;
const int N = 2e5 + 10;
int n;
int p[N];
int lft[N][20], rgt[N][20];
struct node {
int minval;
int maxid, minid;
int lazy;
node() {
minval = 1e9;
maxid = minid = -1;
}
node operator + (const node& other) const {
node ret;
if (minval < other.minval) {
ret = *this;
ret.lazy = 0;
} else if (minval > other.minval) {
ret = other;
ret.lazy = 0;
} else {
ret.minval = minval;
ret.maxid = other.maxid;
ret.minid = minid;
ret.lazy = 0;
}
return ret;
}
} st[N * 4];
void push(int id, int delta) {
st[id].lazy += delta;
st[id].minval += delta;
}
void update(int id, int L, int R, int i, int val) {
if (L == R) {
st[id].minval = val;
st[id].maxid = st[id].minid = L;
return;
}
int mid = L + R >> 1;
push(id * 2, st[id].lazy);
push(id * 2 + 1, st[id].lazy);
st[id].lazy = 0;
if (i <= mid) update(id * 2, L, mid, i, val);
else update(id * 2 + 1, mid + 1, R, i, val);
st[id] = st[id * 2] + st[id * 2 + 1];
}
void add(int id, int L, int R, int u, int v, int delta) {
if (u > R || L > v) return;
if (u <= L && R <= v) {
push(id, delta);
return;
}
int mid = L + R >> 1;
push(id * 2, st[id].lazy);
push(id * 2 + 1, st[id].lazy);
st[id].lazy = 0;
add(id * 2, L, mid, u, v, delta);
add(id * 2 + 1, mid + 1, R, u, v, delta);
st[id] = st[id * 2] + st[id * 2 + 1];
}
node get(int id, int L, int R, int u, int v) {
if (u > R || L > v) return node();
if (u <= L && R <= v) return st[id];
int mid = L + R >> 1;
push(id * 2, st[id].lazy);
push(id * 2 + 1, st[id].lazy);
st[id].lazy = 0;
return get(id * 2, L, mid, u, v) + get(id * 2 + 1, mid + 1, R, u, v);
}
int dist(int x, int y) {
return (y - x + n) % n;
}
void init(int k, vector<int> r) {
n = r.size();
for (int i = 0; i < n; ++i) update(1, 0, n - 1, i, r[i]);
auto check = [&](int i) {
if (get(1, 0, n - 1, i, i).minval > 0) return 0;
if (i - k + 1 < 0) {
if (get(1, 0, n - 1, 0, i - 1).minval <= 0) return 0;
if (get(1, 0, n - 1, (i - k + 1 + n) % n, n - 1).minval <= 0) return 0;
return 1;
} else {
if (get(1, 0, n - 1, i - k + 1, i - 1).minval <= 0) return 0;
return 1;
}
};
auto get_next = [&](int u) {
if (st[1].minval > 0) return -1;
node cur = get(1, 0, n - 1, u, n - 1);
if (cur.minval <= 0) return cur.minid;
cur = get(1, 0, n - 1, 0, u - 1);
if (cur.minval <= 0) return cur.minid;
return -1;
};
auto get_prev = [&](int u) {
if (st[1].minval > 0) return -1;
node cur = get(1, 0, n - 1, 0, u - 1);
if (cur.minval <= 0) return cur.maxid;
cur = get(1, 0, n - 1, u, n - 1);
if (cur.minval <= 0) return cur.maxid;
return -1;
};
int m = n;
auto add_range = [&](int i, int k) {
if (i - k + 1 < 0) {
if (i != 0) add(1, 0, n - 1, 0, i - 1, -1);
add(1, 0, n - 1, (i - k + 1 + n) % n, n - 1, -1);
} else {
add(1, 0, n - 1, i - k + 1, i - 1, -1);
}
};
function <void(int)> dfs = [&](int u) {
while (1) {
int v = get_prev(u);
if (v != u && dist(v, u) + 1 <= k) {
dfs(v);
}
else break;
}
p[u] = --m;
add_range(u, k);
update(1, 0, n - 1, u, 1e9);
};
while (st[1].minval <= 0) {
int i = st[1].minid;
dfs(i);
}
for (int i = 0; i < N * 4; ++i) st[i] = node();
vector <int> s(n);
for (int i = 0; i < n; ++i) s[p[i]] = i;
for (int id = 0; id < n; ++id) {
int i = s[id];
if (i - k + 1 >= 0) {
lft[i][0] = get(1, 0, n - 1, i - k + 1, i - 1).minid;
} else {
lft[i][0] = (get(1, 0, n - 1, 0, i - 1) + get(1, 0, n - 1, (i - k + 1 + n) % n, n - 1)).minid;
}
if (i + k - 1 < n) {
rgt[i][0] = get(1, 0, n - 1, i + 1, i + k - 1).minid;
} else {
rgt[i][0] = (get(1, 0, n - 1, i + 1, n - 1) + get(1, 0, n - 1, 0, (i + k - 1) % n)).minid;
}
update(1, 0, n - 1, i, - p[i]);
}
for (int i = 0; i < n; ++i) {
if (lft[i][0] == -1) lft[i][0] = i;
if (rgt[i][0] == -1) rgt[i][0] = i;
lft[i][0] = dist(lft[i][0], i);
rgt[i][0] = dist(i, rgt[i][0]);
}
for (int lg = 1; lg < 20; ++lg) {
for (int i = 0; i < n; ++i) {
lft[i][lg] = min(lft[i][lg - 1] + lft[(i - lft[i][lg - 1] % n + n) % n][lg - 1], n);
rgt[i][lg] = min(rgt[i][lg - 1] + rgt[(i + rgt[i][lg - 1]) % n][lg - 1], n);
}
}
}
int reachable(int x, int y) {
int w = x;
for (int i = 19; i >= 0; --i)
if (dist(w, x) + lft[w][i] < dist(y, x)) {
w = (w - lft[w][i] % n + n) % n;
}
if (lft[w][0] && p[w] > p[y]) return 1;
w = x;
for (int i = 19; i >= 0; --i)
if (dist(x, w) + rgt[w][i] < dist(x, y)) {
w = (w + rgt[w][i]) % n;
}
if (rgt[w][0] && p[w] > p[y]) return 1;
return 0;
}
int compare_plants(int x, int y) {
if (reachable(x, y)) return 1;
if (reachable(y, x)) return -1;
return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
plants.cpp: In function 'void update(int, int, int, int, int)':
plants.cpp:57:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
57 | int mid = L + R >> 1;
| ~~^~~
plants.cpp: In function 'void add(int, int, int, int, int, int)':
plants.cpp:72:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
72 | int mid = L + R >> 1;
| ~~^~~
plants.cpp: In function 'node get(int, int, int, int, int)':
plants.cpp:84:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
84 | int mid = L + R >> 1;
| ~~^~~
plants.cpp: In function 'void init(int, std::vector<int>)':
plants.cpp:99:10: warning: variable 'check' set but not used [-Wunused-but-set-variable]
99 | auto check = [&](int i) {
| ^~~~~
plants.cpp:110:10: warning: variable 'get_next' set but not used [-Wunused-but-set-variable]
110 | auto get_next = [&](int u) {
| ^~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |