BZOJ 2726 任务安排

来一发cdq吧。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 500050
#define inf 0x7f7f7f7f7f7f7f7fLL
using namespace std;
long long n,s,t[maxn],f[maxn],dp[maxn],st[maxn];
struct pnt
{
    long long x,y,k,id;
    friend bool operator < (const pnt &x,const pnt &y)
    {
        return x.k<y.k;
    }
}p[maxn],rt[maxn];
long long read()
{
    char ch;long long data=0,f=1;
    while (ch<'0' || ch>'9')  {if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0' && ch<='9') {data=data*10+ch-'0';ch=getchar();}
    return data*f;
}
bool cmp(pnt x,pnt y) {return x.x<y.x || (x.x==y.x && x.y<y.y);}
long long U(long long x,long long y) {return p[x].y-p[y].y;}
long long D(long long x,long long y) {return p[x].x-p[y].x;}
void cdq(long long left,long long right)
{
    if (left==right)
    {
        p[left].x=f[left];p[left].y=dp[left]-f[n]*t[left]+f[left]*t[left]-f[left]*s;
        return;
    }
    long long mid=(left+right)>>1,l1=left,l2=mid+1;
    for (long long i=left;i<=right;i++)
    {
        if (p[i].id<=mid) rt[l1++]=p[i];
        else rt[l2++]=p[i];
    }
    memcpy(p+left,rt+left,sizeof(pnt)*(right-left+1));
    cdq(left,mid);
    long long top=0,pp=1;
    for (long long i=left;i<=mid;i++)
    {
        while (top>=2 && U(st[top-1],st[top])*D(st[top-1],i)>U(st[top-1],i)*D(st[top-1],st[top]))
            top--;
        st[++top]=i;
    }
    for (long long i=mid+1;i<=right;i++)
    {
        while (pp<top && U(st[pp+1],st[pp])<p[i].k*D(st[pp+1],st[pp])) pp++;
        dp[p[i].id]=min(dp[p[i].id],dp[p[st[pp]].id]+(f[n]-f[p[st[pp]].id])*(t[p[i].id]-t[p[st[pp]].id]+s));
    }
    cdq(mid+1,right);
    l1=left;l2=mid+1;
    for (long long i=left;i<=right;i++)
    {
        if (l1<=mid && (l2>right || cmp(p[l1],p[l2]))) rt[i]=p[l1++];
        else rt[i]=p[l2++];
    }
    memcpy(p+left,rt+left,sizeof(pnt)*(right-left+1));
    return;
}
int main()
{
    n=read();s=read();
    for (long long i=1;i<=n;i++) 
    {
        t[i]=read();f[i]=read();
        t[i]+=t[i-1];f[i]+=f[i-1];
        p[i].k=t[i];p[i].id=i;
    }
    sort(p,p+n+1);for (long long i=1;i<=n;i++) dp[i]=inf;
    cdq(0,n);
    printf("%lld
",dp[n]);
    return 0;
}
原文地址:https://www.cnblogs.com/ziliuziliu/p/6627066.html