P5665 [CSP-S2019] 划分

写在前面:

毒瘤题,卡空间。

$\mathbf{Part}$ $\mathbb{A}$ :$O(n^3)$

设 $s_n = \sum_{i=1}^{n} a_i$,枚举 $i,j,k$,可以得到 $O(n^3)$ 的做法:$$dp_{i,j} = \min_{s_i-s_j \ge s_j - s_k} \left \{ dp_{j,k} +(s_i-s_j)^2\right \}$$

$\mathbf{Part}$ $\mathbb{B}$ :$O(n^2)$

考虑最后一段,发现最优方案中最后一段一定最小。感性理解下:最后一段越小,相应前面的段也会更小,所以分的段会变多。根据 $(a+b)^2 \ge a^2+b^2$ ,分的段越多,值会越小。设 $d_i$ 为以 $i$ 结尾划分那一段的值,有:$$d_i = s_i - s_{j},j = \max_{s_i-s_k \ge d_k} k$$

$\mathbf{Part}$ $\mathbb{C}$ :$O(n)$

考虑单调队列优化上述过程,做到 $O(n)$

注意事项:节约空间

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 4e7 + 1, M = 1e5 + 1;
const int Mo = 1 << 30;
int n, T, t[N], q[N], h, tl, m, x, y, z;
vector<int>b, p, l, r;
vector<ll>f, s;
void write(__int128 x) {
    if(x > 9) write(x / 10);
    putchar(x % 10 + '0');
}
int main(){
    scanf("%d %d", &n, &T); s.resize(n + 1);
    if(T == 1) {
        b.resize(n + 1), p.resize(M), l.resize(M), r.resize(M);
        scanf("%d %d %d %d %d %d", &x, &y, &z, &b[1], &b[2], &m);
        for(int i = 1 ; i <= m ; i ++) scanf("%d %d %d", &p[i], &l[i], &r[i]);  
        for(int i = 3 ; i <= n ; i ++) b[i] = (0ll + 1ll * b[i - 1] * x + 1ll * b[i - 2] * y + z) % Mo ;
        for(int i = 1 ; i <= m ; i ++)
        for(int j = p[i - 1] + 1 ; j <= p[i] ; j ++) { s[j] = (b[j] % (r[i] - l[i] + 1)) + l[i] ; s[j] += s[j - 1]; } 
        b.resize(0), p.resize(0), l.resize(0), r.resize(0);
        b.clear(), p.clear(), l.clear(), r.clear();
        b.shrink_to_fit(), p.shrink_to_fit(), l.shrink_to_fit(), r.shrink_to_fit();
    }
    else {
        for(int i = 1;i <= n;i++) scanf("%lld", &s[i]);
        for(int i = 1;i <= n;i++) s[i] += s[i - 1];
    }
    f.resize(n + 1);
    q[h = tl = 1] = 0;
    for(int i = 1;i <= n;i++) {
        while(h < tl && s[i] >= f[q[h + 1]] + s[q[h + 1]]) h++;
        f[i] = s[i] - s[q[h]], t[i] = q[h];
        while(h < tl && f[q[tl]] + s[q[tl]] >= f[i] + s[i]) tl--;
        q[++tl] = i;
    }
    __int128 ans = 0;
    for(int i = n;i ;i = t[i]) ans += (__int128)f[i] * f[i];
    write(ans);
    return 0;
}
posted @ 2023-10-18 17:53  Saka_Noa  阅读(23)  评论(0)    收藏  举报  来源