提出 #61737428
ソースコード 拡げる
#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';
}
}
提出情報
コンパイルエラー
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++;
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~
ジャッジ結果
| セット名 |
Sample |
All |
| 得点 / 配点 |
0 / 0 |
400 / 400 |
| 結果 |
|
|
| セット名 |
テストケース |
| 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 |
| ケース名 |
結果 |
実行時間 |
メモリ |
| 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 |