/*那天我们说随机一道2开头的题,随机了很多权限题,然后就随机到了这道;
当时我还不会斜率优化 所以不会qaq;
昨天学了斜率优化_dafahao,突然懂了;
c[i]=∑t[i],s[i]=∑t[i]*i;
于是dp[i]=m+min(dp[j+1]+s[j]-s[i]-i*(c[j]-c[i]));(在i处强行建车站 最后到0处减去m就可以辣(╯‵□′)╯︵┻━┻)
然后考虑斜率优化 设j比k更优;
有dp[j+1]+s[j]-i*c[j]<dp[k+1]+s[k]-i*c[k];
令y[i]=dp[i+1]+s[i]有 y[j]-y[k]<i*(c[j]-c[k])然后就随便搞一搞就出来了;
要不我们再随机一道wsq嘛qaq;
今天下午打ACM,%司机,%白爷爷,%yj秋;
By——WXH
P.S.我的程序跑了2000+ms,榜上200+ms的怎么跑的qaq*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
const int maxn=1000010;
int n,m,q[maxn],mx,head,tail;
LL dp[maxn],y[maxn],c[maxn],s[maxn],t[maxn];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
int pos,val;
scanf("%d%d",&pos,&val);
mx=max(mx,pos);
t[pos]+=val;
}
for(int i=1;i<=mx;i++)
{
c[i]=c[i-1]+t[i];
s[i]=s[i-1]+t[i]*i;
}
dp[mx]=m;
head=tail=1;
q[1]=mx;
y[mx]=s[mx];
for(int i=mx-1;i>=0;i--)
{
while(head<tail&&y[q[head+1]]-y[q[head]]<i*(c[q[head+1]]-c[q[head]]))
head++;
dp[i]=dp[q[head]+1]+s[q[head]]-s[i]-(c[q[head]]-c[i])*i+m;
y[i]=dp[i+1]+s[i];
while(head<tail&&(y[q[tail]]-y[q[tail-1]])*(c[i]-c[q[tail]])<=(y[i]-y[q[tail]])*(c[q[tail]]-c[q[tail-1]]))
tail--;
q[++tail]=i;
}
printf("%lld",dp[0]-m);
}
bzoj 2153
最新推荐文章于 2019-03-15 14:32:00 发布