P8476 「GLR-R3」惊蛰
C. P8476「GLR-R3」惊蛰
考虑 DP,设
考虑转移的本质,对
根据上述分析,对
将
- 区间给位置
i 加上a_i 。 - 区间加法。
- 区间赋值。
- 线段树二分
< p 的位置最后一个> v 的位置q ,保证< p 的位置具有单调性。
维护区间最大值和赋值,加法,加
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
#define TIME 1e3 * clock() / CLOCKS_PER_SEC
bool Mbe;
constexpr int N = 1e6 + 5;
ll val[N << 2], b[N];
struct tag {
ll ass, add, badd;
tag operator + (const tag &x) const {
if(x.ass != -1) return x;
tag z = *this;
z.add += x.add, z.badd += x.badd;
return z;
}
} laz[N << 2];
void eff(int l, ll x, tag v) {
if(v.ass != -1) val[x] = v.ass;
val[x] += v.add + b[l] * v.badd;
laz[x] = laz[x] + v;
}
void down(int l, int r, int x) {
int m = l + r >> 1;
eff(m, x << 1, laz[x]);
eff(r, x << 1 | 1, laz[x]);
laz[x] = {-1, 0, 0};
}
void modify(int l, int r, int ql, int qr, int x, tag v) {
if(ql > qr) return;
if(ql <= l && r <= qr) return eff(r, x, v);
int m = l + r >> 1;
down(l, r, x);
if(ql <= m) modify(l, m, ql, qr, x << 1, v);
if(m < qr) modify(m + 1, r, ql, qr, x << 1 | 1, v);
val[x] = max(val[x << 1], val[x << 1 | 1]);
}
int binary(int l, int r, int p, int x, ll lim) { // find the first position that val[x] >= lim
if(r <= p && val[x] < lim) return -1;
if(l == r) return l;
int m = l + r >> 1;
down(l, r, x);
int res = binary(l, m, p, x << 1, lim);
if(res != -1) return res;
res = m < p ? binary(m + 1, r, p, x << 1 | 1, lim) : -1;
return res;
}
ll query(int l, int r, int p, int x) {
if(l == r) return val[x];
int m = l + r >> 1;
down(l, r, x);
if(p <= m) return query(l, m, p, x << 1);
return query(m + 1, r, p, x << 1 | 1);
}
int n, C, a[N];
bool Med;
int main() {
fprintf(stderr, "%.3lf MB\n", (&Mbe - &Med) / 1048576.0);
#ifdef ALEX_WEI
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);
#endif
ios::sync_with_stdio(0);
cin >> n >> C;
for(int i = 1; i <= n; i++) cin >> a[i], b[i] = a[i];
sort(b + 1, b + n + 1);
for(int i = 1; i <= n << 2; i++) laz[i].ass = -1;
for(int i = 1; i <= n; i++) {
int p = lower_bound(b + 1, b + n + 1, a[i]) - b;
modify(1, n, p + 1, n, 1, (tag) {-1, -a[i], 1});
if(p == 1) continue;
modify(1, n, 1, p - 1, 1, (tag) {-1, C, 0});
ll v = query(1, n, p, 1);
int pos = binary(1, n, p - 1, 1, v);
if(pos != -1) modify(1, n, pos, p - 1, 1, (tag) {v, 0, 0});
}
cout << query(1, n, 1, 1) << "\n";
cerr << TIME << " ms\n";
return 0;
}
/*
2022/8/14
Author: Alex_Wei
start coding at 15:55
finish debugging at 16:40
*/