[Noip2018普及组]摆渡车

#include
#define MAXT 4000505
using namespace std;
int n, m, cnt[MAXT], sum[MAXT], f[MAXT], que[MAXT], Maxt;
int main(){
    scanf("%d%d", &n, &m);
    for (int i=1; i<=n; i++){
        int x;
        scanf("%d", &x);
        cnt[x]++, sum[x]+=x;
        Maxt=max(Maxt, x);
    }
    for (int i=1; i<Maxt+m; i++) cnt[i]+=cnt[i-1], sum[i]+=sum[i-1];
    int head=1, tail=0;
    for (int i=1; i<Maxt+m; i++){
        if (i>=m) {
            while (head<tail && (f[que[tail]]+sum[que[tail]]-f[que[tail-1]]-sum[que[tail-1]])*(cnt[i-m]-cnt[que[tail]])>=(f[i-m]+sum[i-m]-f[que[tail]]-sum[que[tail]])*(cnt[que[tail]]-cnt[que[tail-1]])) --tail;
            que[++tail]=i-m;
        }
        while (head<tail && i*(cnt[que[head+1]]-cnt[que[head]])>=(f[que[head+1]]+sum[que[head+1]]-f[que[head]]-sum[que[head]])) ++head;
        f[i]=cnt[i]*i-sum[i];
        if (head<=tail) f[i]=min(f[i], f[que[head]]+(cnt[i]-cnt[que[head]])*i-(sum[i]-sum[que[head]]));
    }
    int ans=1000000000;
    for (int i=Maxt; i<Maxt+m; i++) ans=min(ans, f[i]);
    printf("%d\n", ans);
    return 0;
}

你可能感兴趣的:([Noip2018普及组]摆渡车)