来一发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\n",dp[n]); return 0; }