제출 #562428

#제출 시각아이디문제언어결과실행 시간메모리
562428Lucina사탕 분배 (IOI21_candies)C++17
100 / 100
618 ms44312 KiB
#include "candies.h" #include <vector> #include <bits/stdc++.h> using namespace std; const int nax = 2e5 + 10; int n, q; const int64_t INF = 1e15; struct seg_node { int64_t mn, mx; int min_ind, max_ind; seg_node() :mn(INF), mx(-INF) {} seg_node(int64_t x, int id): mn(x), mx(x), min_ind(id), max_ind(id){} inline int64_t dif() {return mx - mn;} inline void apply(int64_t x) { mn += x; mx += x; } }; int64_t bit[nax]; void update(int idx, int64_t val) { for (; idx <= q ; idx += idx & -idx) bit[idx] += val; } int64_t get_sum(int idx) { int64_t res = 0; for (; idx > 0; idx -= idx & -idx) res += bit[idx]; return res; } seg_node operator +(const seg_node &a, const seg_node &b) { seg_node res; res.min_ind = a.mn < b.mn ? (res.mn = a.mn, a.min_ind) : (res.mn = b.mn, b.min_ind); res.max_ind = a.mx > b.mx ? (res.mx = a.mx, a.max_ind) : (res.mx = b.mx, b.max_ind); return res; } seg_node sg[nax << 2]; int64_t tag[nax << 2]; void push(int v) { if (!tag[v]) return; sg[v << 1].apply(tag[v]); sg[v << 1 | 1].apply(tag[v]); tag[v << 1] += tag[v]; tag[v << 1 | 1] += tag[v]; tag[v] = 0; } void range_add(int v, int x, int y, int l, int r, int64_t add) { if (x != y) push(v); if (l == x && r == y) { tag[v] += add; sg[v].apply(add); if (x != y) push(v); return; } int mid = x + y >> 1; if (r <= mid) range_add(v << 1, x, mid, l, r, add); else if (l > mid) range_add(v * 2 + 1, mid + 1, y, l, r, add); else range_add(v << 1, x, mid, l, mid, add), range_add(v * 2 + 1, mid + 1, y, mid + 1, r, add); sg[v] = sg[v << 1] + sg[v << 1 | 1]; } /// find maximum index such that /// max(index, q) - min(index, q) >= k int find_last(int v, int l, int r, int tar, seg_node &info) { if (l == r) return (info + sg[v]).dif() >= tar ? l : -1; push(v); if ((info + sg[v]).dif() < tar) return -1; int mid = l + r >> 1; seg_node info_right = info + sg[v << 1 | 1]; if (info_right.dif() >= tar) return find_last(v << 1 | 1, mid + 1, r, tar, info); info = info_right; return find_last(v << 1, l, mid, tar, info); } void build(int v, int l, int r) { if (l == r) { sg[v] = seg_node(0, l); } else { int mid = l + r >> 1; build(v << 1, l, mid); build(v << 1 | 1, mid + 1, r); sg[v] = sg[v << 1] + sg[v << 1 | 1]; } } std::vector<int> distribute_candies(std::vector<int> c, std::vector<int> l, std::vector<int> r, std::vector<int> v) { n = c.size(); q = v.size(); vector <vector <pair <int, int>>> sc(n + 1); for (int i = 0 ; i < q ; ++ i) { sc[l[i]].emplace_back(i + 1, v[i]); sc[r[i] + 1].emplace_back(i + 1, -v[i]); } build(1, 0, q); vector <int> ans(n); int64_t all_sum = 0; for (int s = 0 ; s < n ; ++ s) { int k = c[s]; for (auto &[idx, val] : sc[s]) { update(idx, val); all_sum += val; range_add(1, 0, q, idx, q, val); } seg_node info; int ans1 = find_last(1, 0, q, k, info); if (ans1 == -1) { int min_ind = sg[1].min_ind; ans[s] = all_sum - get_sum(min_ind); } else { int64_t cur_val = get_sum(ans1); int lst_ind; if (cur_val < info.mx) lst_ind = info.max_ind; else lst_ind = info.min_ind; int64_t res = lst_ind == q ? 0 : all_sum - get_sum(lst_ind); if (cur_val < info.mx) ans[s] = k + res; else ans[s] = res; } } return ans; }

컴파일 시 표준 에러 (stderr) 메시지

candies.cpp: In function 'void range_add(int, int, int, int, int, int64_t)':
candies.cpp:57:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   57 |     int mid = x + y >> 1;
      |               ~~^~~
candies.cpp: In function 'int find_last(int, int, int, int, seg_node&)':
candies.cpp:71:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   71 |     int mid = l + r >> 1;
      |               ~~^~~
candies.cpp: In function 'void build(int, int, int)':
candies.cpp:82:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   82 |         int mid = l + r >> 1;
      |                   ~~^~~
#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...