Submission #61737428
Source Code Expand
#include <cassert>
#include <algorithm>
#include <vector>
#include <numeric>
constexpr int bit_ceil_log(unsigned int n) {
int x = 0;
while ((1 << x) < (unsigned int)(n)) x++;
return x;
}
template <typename T, typename Tsum>
struct beats {
public:
static constexpr T inf = std::numeric_limits<T>::max();
static constexpr T minf = std::numeric_limits<T>::min();
private:
struct S{
T min, second_min, max, second_max;
Tsum sum;
int min_cnt, max_cnt;
S(): min(inf), second_min(inf), max(minf), second_max(minf), sum(0), min_cnt(0), max_cnt(0){}
S(T x): min(x), second_min(inf), max(x), second_max(minf), sum(x), min_cnt(1), max_cnt(1){}
};
struct F{
T add, lower, upper;
F(): add(0), lower(minf), upper(inf){}
F(T a, T b, T c): add(a), lower(b), upper(c){}
void reset(){
add = 0;
lower = minf;
upper = inf;
}
};
int _n, size, log;
std::vector<S> d;
std::vector<F> lz;
std::vector<int> que;
// v, lにfを作用
void propagate(S &v, int len, F &l, const F &f) {
if(f.add) {
l.add += f.add;
if (l.lower != minf) l.lower += f.add;
if (l.upper != inf) l.upper += f.add;
v.min += f.add;
if (v.second_min != inf) v.second_min += f.add;
v.max += f.add;
if (v.second_max != minf) v.second_max += f.add;
v.sum += (Tsum)f.add * len;
}
if(v.min < f.lower) {
l.lower = f.lower;
if (v.max < f.lower) l.upper = f.lower;
v.sum += (Tsum)(f.lower - v.min) * v.min_cnt;
if (v.second_max == v.min) v.second_max = f.lower;
else if (v.max == v.min) v.max = f.lower, v.second_max = minf;
v.min = f.lower;
}
if(f.upper < v.max) {
l.upper = f.upper;
if (f.upper < v.min) l.lower = f.upper;
v.sum -= (Tsum)(v.max - f.upper) * v.max_cnt;
if (v.second_min == v.max) v.second_min = f.upper;
else if (v.min == v.max) v.min = f.upper, v.second_min = inf;
v.max = f.upper;
}
}
void update_inplace(S &v, const S &l, const S &r) {
v.sum = l.sum + r.sum;
if(l.max == r.max) {
v.max = l.max;
v.max_cnt = l.max_cnt + r.max_cnt;
v.second_max = std::max(l.second_max, r.second_max);
} else if(l.max > r.max) {
v.max = l.max;
v.max_cnt = l.max_cnt;
v.second_max = std::max(l.second_max, r.max);
} else {
v.max = r.max;
v.max_cnt = r.max_cnt;
v.second_max = std::max(l.max, r.second_max);
}
if(l.min == r.min) {
v.min = l.min;
v.min_cnt = l.min_cnt + r.min_cnt;
v.second_min = std::min(l.second_min, r.second_min);
} else if(l.min < r.min) {
v.min = l.min;
v.min_cnt = l.min_cnt;
v.second_min = std::min(l.second_min, r.min);
} else {
v.min = r.min;
v.min_cnt = r.min_cnt;
v.second_min = std::min(l.min, r.second_min);
}
}
// prod sumで使う
void propagate_prod_sum(S &v, int len, const F &f) {
if(f.add) {
v.min += f.add;
v.max += f.add;
v.sum += (Tsum)f.add * len;
}
if(v.min < f.lower) {
v.sum += (Tsum)(f.lower - v.min) * v.min_cnt;
if (v.max == v.min) v.max = f.lower;
v.min = f.lower;
}
if(f.upper < v.max) {
v.sum -= (Tsum)(v.max - f.upper) * v.max_cnt;
if (v.min == v.max) v.min = f.upper;
v.max = f.upper;
}
}
// prod sumで使う
void update_prod_sum(S &v, const S &u) {
v.sum += u.sum;
if (v.max <= u.max) {
v.max_cnt = u.max_cnt + (v.max == u.max ? v.max_cnt : 0);
v.max = u.max;
}
if (v.min >= u.min) {
v.min_cnt = u.min_cnt + (v.min == u.min ? v.min_cnt : 0);
v.min = u.min;
}
}
void update(int k) { update_inplace(d[k], d[2 * k], d[2 * k + 1]); }
void all_apply(int k, const F &f) {
propagate(d[k], 1 << (log - 31 + __builtin_clz(k)), lz[k], f);
}
void all_apply_chmin(int k, T f) {
int pos = 0;
que[pos] = k;
while(pos >= 0) {
int idx = que[pos--];
if (idx < 0) {
update(-idx);
} else if (d[idx].max <= f) {
} else if(d[idx].second_max < f) {
propagate(d[idx], 0, lz[idx], F(0, minf, f));
} else {
push(idx);
que[++pos] = -idx;
que[++pos] = idx * 2;
que[++pos] = idx * 2 + 1;
}
}
}
void all_apply_chmax(int k, T f) {
int pos = 0;
que[pos] = k;
while(pos >= 0) {
int idx = que[pos--];
if (idx < 0) {
update(-idx);
} else if (f <= d[idx].min) {
} else if(f < d[idx].second_min) {
propagate(d[idx], 0, lz[idx], F(0, f, inf));
} else {
push(idx);
que[++pos] = -idx;
que[++pos] = idx * 2;
que[++pos] = idx * 2 + 1;
}
}
}
void all_apply_add(int k, T f) {
propagate(d[k], 1 << (log - 31 + __builtin_clz(k)), lz[k], F(f, minf, inf));
}
void push(int k) {
if (lz[k].add == 0 && lz[k].lower == minf && lz[k].upper == inf) return;
all_apply(2 * k, lz[k]);
all_apply(2 * k + 1, lz[k]);
lz[k].reset();
}
public:
beats() : beats(0) {}
// n要素の0で初期化
beats(int n) : beats(std::vector<T>(n, T(0))) {}
beats(const std::vector<T>& v) : _n(int(v.size())) {
log = bit_ceil_log((unsigned int)_n);
size = 1 << log;
d = std::vector<S>(2 * size, S());
lz = std::vector<F>(2 * size, F());
que = std::vector<int>(2 * size);
for (int i = 0; i < _n; i++) d[size + i] = S(v[i]);
for (int i = size - 1; i >= 1; i--) update(i);
}
void set(int p, T x) {
assert(0 <= p && p < _n);
p += size;
for (int i = log; i >= 1; i--) push(p >> i);
d[p] = x;
for (int i = 1; i <= log; i++) update(p >> i);
}
T get(int p) {
assert(0 <= p && p < _n);
p += size;
for (int i = log; i >= 1; i--) push(p >> i);
return d[p].min;
}
T prod_min(int l, int r) {
assert(0 <= l && l <= r && r <= _n);
if (l == r) return inf;
l += size;
r += size;
T sml = inf, smr = inf;
int i = 1, l2 = l, r2 = r;
for (; l < r; i++, l >>= 1, r >>= 1) {
if (l & 1) sml = std::min(sml, d[l++].min);
if (r & 1) smr = std::min(d[--r].min, smr);
if (sml != inf) sml = std::min(lz[l2 >> i].upper, sml + lz[l2 >> i].add);
if (smr != inf) smr = std::min(lz[(r2 - 1) >> i].upper, smr + lz[(r2 - 1) >> i].add);
}
for (; i <= log; i++) {
if (sml != inf) sml = std::min(lz[l2 >> i].upper, sml + lz[l2 >> i].add);
if (smr != inf) smr = std::min(lz[(r2 - 1) >> i].upper, smr + lz[(r2 - 1) >> i].add);
}
return std::min(sml, smr);
}
T prod_max(int l, int r) {
assert(0 <= l && l <= r && r <= _n);
if (l == r) return minf;
l += size;
r += size;
T sml = minf, smr = minf;
int i = 1, l2 = l, r2 = r;
for (; l < r; i++, l >>= 1, r >>= 1) {
if (l & 1) sml = std::max(sml, d[l++].max);
if (r & 1) smr = std::max(d[--r].max, smr);
if (sml != minf) sml = std::max(lz[l2 >> i].lower, sml + lz[l2 >> i].add);
if (smr != minf) smr = std::max(lz[(r2 - 1) >> i].lower, smr + lz[(r2 - 1) >> i].add);
}
for (; i <= log; i++) {
if (sml != minf) sml = std::max(lz[l2 >> i].lower, sml + lz[l2 >> i].add);
if (smr != minf) smr = std::max(lz[(r2 - 1) >> i].lower, smr + lz[(r2 - 1) >> i].add);
}
return std::max(sml, smr);
}
Tsum prod_sum(int l, int r) {
assert(0 <= l && l <= r && r <= _n);
if (l == r) return 0;
l += size;
r += size;
S sml, smr;
int llen = 0, rlen = 0;
int i = 1, l2 = l, r2 = r;
for (; l < r; i++, l >>= 1, r >>= 1) {
if (l & 1) update_prod_sum(sml, d[l++]), llen += 1 << (i - 1);
if (r & 1) update_prod_sum(smr, d[--r]), rlen += 1 << (i - 1);
if (llen) propagate_prod_sum(sml, llen, lz[l2 >> i]);
if (rlen) propagate_prod_sum(smr, rlen, lz[(r2 - 1) >> i]);
}
for (; i <= log; i++) {
if (llen) propagate_prod_sum(sml, llen, lz[l2 >> i]);
if (rlen) propagate_prod_sum(smr, rlen, lz[(r2 - 1) >> i]);
}
return sml.sum + smr.sum;
}
S prod_all_info(int l, int r) {
assert(0 <= l && l <= r && r <= _n);
if (l == r) return S();
l += size;
r += size;
for (int i = log; i >= 1; i--) {
if (((l >> i) << i) != l) push(l >> i);
if (((r >> i) << i) != r) push((r - 1) >> i);
}
S res, tmp;
for (; l < r; l >>= 1, r >>= 1) {
if (l & 1) {
tmp = res;
update_inplace(res, tmp, d[l++]);
}
if (r & 1) {
tmp = res;
update_inplace(res, tmp, d[--r]);
}
}
return res;
}
void apply(int p, F f) {
assert(0 <= p && p < _n);
p += size;
for (int i = log; i >= 1; i--) push(p >> i);
d[p] = mapping(f, d[p]);
for (int i = 1; i <= log; i++) update(p >> i);
}
void apply_add(int l, int r, T f) {
assert(0 <= l && l <= r && r <= _n);
if (l == r) return;
l += size;
r += size;
for (int i = log; i >= 1; i--) {
if (((l >> i) << i) != l) push(l >> i);
if (((r >> i) << i) != r) push((r - 1) >> i);
}
{
int l2 = l, r2 = r;
while (l < r) {
if (l & 1) all_apply_add(l++, f);
if (r & 1) all_apply_add(--r, f);
l >>= 1;
r >>= 1;
}
l = l2;
r = r2;
}
for (int i = 1; i <= log; i++) {
if (((l >> i) << i) != l) update(l >> i);
if (((r >> i) << i) != r) update((r - 1) >> i);
}
}
void apply_chmin(int l, int r, T f) {
assert(0 <= l && l <= r && r <= _n);
if (l == r) return;
l += size;
r += size;
for (int i = log; i >= 1; i--) {
if (((l >> i) << i) != l) push(l >> i);
if (((r >> i) << i) != r) push((r - 1) >> i);
}
{
int l2 = l, r2 = r;
while (l < r) {
if (l & 1) all_apply_chmin(l++, f);
if (r & 1) all_apply_chmin(--r, f);
l >>= 1;
r >>= 1;
}
l = l2;
r = r2;
}
for (int i = 1; i <= log; i++) {
if (((l >> i) << i) != l) update(l >> i);
if (((r >> i) << i) != r) update((r - 1) >> i);
}
}
void apply_chmax(int l, int r, T f) {
assert(0 <= l && l <= r && r <= _n);
if (l == r) return;
l += size;
r += size;
for (int i = log; i >= 1; i--) {
if (((l >> i) << i) != l) push(l >> i);
if (((r >> i) << i) != r) push((r - 1) >> i);
}
{
int l2 = l, r2 = r;
while (l < r) {
if (l & 1) all_apply_chmax(l++, f);
if (r & 1) all_apply_chmax(--r, f);
l >>= 1;
r >>= 1;
}
l = l2;
r = r2;
}
for (int i = 1; i <= log; i++) {
if (((l >> i) << i) != l) update(l >> i);
if (((r >> i) << i) != r) update((r - 1) >> i);
}
}
};
#include <iostream>
int main() {
std::cin.tie(nullptr);
std::ios::sync_with_stdio(false);
int N;
std::cin >> N;
std::vector<long long> A(N);
for (int i = 0; i < N; i++) std::cin >> A[i];
beats<long long, long long> seg(A);
for (int i = 0; i < N; i++) {
auto tmp = seg.prod_all_info(0, i);
int cnt = i - (tmp.min == 0 ? tmp.min_cnt : 0);
seg.set(i, A[i] + cnt);
seg.apply_add(0, i, -1);
seg.apply_chmax(0, i, 0);
}
for (int i = 0; i < N; i++) {
std::cout << seg.get(i) << '\n';
}
}
Submission Info
Submission Time
2025-01-17 01:30:00+0900
Task
D - Coming of Age Celebration
User
tonegawa
Language
C++ 23 (gcc 12.2)
Score
400
Code Size
13345 Byte
Status
AC
Exec Time
610 ms
Memory
85832 KiB
Compile Error
Main.cpp: In function ‘constexpr int bit_ceil_log(unsigned int)’:
Main.cpp:8:21: warning: comparison of integer expressions of different signedness: ‘int’ and ‘unsigned int’ [-Wsign-compare]
8 | while ((1 << x) < (unsigned int)(n)) x++;
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~
Judge Result
Set Name
Sample
All
Score / Max Score
0 / 0
400 / 400
Status
Set Name
Test Cases
Sample
sample00.txt, sample01.txt, sample02.txt
All
sample00.txt, sample01.txt, sample02.txt, testcase00.txt, testcase01.txt, testcase02.txt, testcase03.txt, testcase04.txt, testcase05.txt, testcase06.txt, testcase07.txt, testcase08.txt, testcase09.txt, testcase10.txt, testcase11.txt, testcase12.txt, testcase13.txt, testcase14.txt, testcase15.txt, testcase16.txt, testcase17.txt, testcase18.txt, testcase19.txt
Case Name
Status
Exec Time
Memory
sample00.txt
AC
1 ms
3640 KiB
sample01.txt
AC
1 ms
3504 KiB
sample02.txt
AC
1 ms
3448 KiB
testcase00.txt
AC
1 ms
3636 KiB
testcase01.txt
AC
450 ms
84836 KiB
testcase02.txt
AC
504 ms
85832 KiB
testcase03.txt
AC
492 ms
84168 KiB
testcase04.txt
AC
608 ms
85068 KiB
testcase05.txt
AC
142 ms
43212 KiB
testcase06.txt
AC
610 ms
85056 KiB
testcase07.txt
AC
470 ms
84064 KiB
testcase08.txt
AC
610 ms
85060 KiB
testcase09.txt
AC
497 ms
84156 KiB
testcase10.txt
AC
608 ms
85052 KiB
testcase11.txt
AC
211 ms
43460 KiB
testcase12.txt
AC
606 ms
85124 KiB
testcase13.txt
AC
362 ms
83360 KiB
testcase14.txt
AC
605 ms
85172 KiB
testcase15.txt
AC
54 ms
13400 KiB
testcase16.txt
AC
607 ms
85172 KiB
testcase17.txt
AC
490 ms
84072 KiB
testcase18.txt
AC
441 ms
84676 KiB
testcase19.txt
AC
426 ms
84656 KiB