單調(diào)隊列 斜率優(yōu)化

斜率優(yōu)化

#include<bits/stdc++.h>
using namespace std;
struct fastio
{
    fastio&operator-(int&a)
    {
        a=0; int n=0; char c=getchar();
        while(c<'0'||c>'9') c=='-'&&(n=1), c=getchar();
        while(c>='0'&&c<='9') a=a*10+(c&15), c=getchar();
        n&&(a=-a); return *this;
    }
}in;
const int N = 4e6+100;
int f[N], c[N], s[N]; 
inline double slope(int i, int j)
{
    return (double) (f[j]+s[j]-f[i]-s[i]) / (c[i]==c[j] ? 1e-9 : c[j]-c[i]);
}
int main()
{
    freopen("a.txt", "r", stdin);
    int n,m;
    in-n-m;
    int t, maxT=0;
    for(int i=1; i<=n; i++) in-t, maxT = max(maxT, t), c[t]++, s[t]+=t;
    int bound  = maxT + m;
    for(int i=1; i^bound; i++) c[i]+=c[i-1], s[i]+=s[i-1];
    static int q[N], l=1, r;
    for(int i=0; i^bound; i++)
    {
        if(i>=m)
        {                                               //actually i-m
            while(l<r && slope(q[r-1], q[r])>=slope(q[r], i-m)) r--;
            q[++r] = i-m;
        }
        while(l<r && slope(q[l], q[l+1])<=i) l++;
        f[i] = i*c[i]-s[i];
        if(l<=r) f[i] = min(f[i], f[q[l]]+i*(c[i]-c[q[l]])+s[q[l]]-s[i]);
    }
    int ans = 1e9;
    for(int i=maxT; i^bound; i++) ans= min(ans, f[i]);
    printf("%d", ans);
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容