noi2015模板-决策单调性

时间:2022-01-24 18:57:25

bzoj1010

#include <bits/stdc++.h>

using namespace std;

#define rep(i, l, r) for (LL i = l; i <= r; i++)
#define REP(i, l, r) for (LL i = l; i >= r; i--)
#define MAXN 1000010

typedef long long LL;
LL n, L, c[MAXN], f[MAXN], top, sumc[MAXN];
struct interval {LL i, l, r;} stk[MAXN];

inline LL sum(LL l, LL r) {return sumc[r] - sumc[l-1];}
inline LL sqr(LL n) {return n*n;}
inline LL cost(LL l, LL r) {return sqr(r-l + sum(l, r) - L);}
inline LL F(LL x, LL j) {return f[j] + cost(j+1, x);}

inline LL search(LL L, LL R, LL cur, LL old) {
    while (R-L > 1) {
	LL mid = (L+R) >> 1;
	if (F(mid, cur) <= F(mid, old)) R = mid; else L = mid;
    }
    return (F(L, cur) <= F(L, old)) ? L : R;
}

int main() {
    cin >> n >> L;
    rep(i, 1, n) scanf("%lld", c + i), sumc[i] = sumc[i-1] + c[i];
    stk[top = 1] = interval{0, 1, n};
    rep(i, 1, n) {
        interval cur = interval{i, i+1, n}, state;
        REP(j, top, 1) if (stk[j].l <= i && stk[j].r >= i) {state = stk[j]; break;}
	f[i] = F(i, state.i);
	while (stk[top].l > i && F(stk[top].l, i) <= F(stk[top].l, stk[top].i)) cur.l = stk[top].l, top--;
        if (F(n, i) >= F(n, stk[top].i)) continue;
	LL mid = search(i+1, n, i, stk[top].i);
	stk[top].r = mid-1; cur.l = mid; stk[++top] = cur;
    }
    cout << f[n] << endl;
    
    return 0;
}