제출 #569514

#제출 시각아이디문제언어결과실행 시간메모리
569514hoanghq2004식물 비교 (IOI20_plants)C++14
100 / 100
958 ms56092 KiB
#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 timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...