cdq复健.jpg

首先列个n方递推,设sf是f的前缀和,st是t的前缀和:

\[f[i]=min(f[j]+s*(sf[n]-sf[j])+st[i]*(sf[i]-sf[j]))
\]

然后移项:

\[f[i]=f[j]+s*sf[n]-s*sf[j]+st[i]*sf[i]-st[i]*sf[j]
\]

\[f[i]=f[j]+s*sf[n]+st[i]*sf[i]-s*sf[j]-st[i]*sf[j]
\]

\[f[i]=f[j]+s*sf[n]+st[i]*sf[i]-sf[j]*(s+st[i])
\]

\[f[i]+sf[j]*(s+st[i])=f[j]+s*sf[n]+st[i]*sf[i]
\]

然后看成斜率表达式b+kx=y,那么

\[b=f[i],x=sf[j],k=(s+st[i]),y=f[j]+s*sf[n]+st[i]*sf[i]
\]

然后因为有负数所以这并不能用单调队列,splay是很方便但是又太长了

选择cdq

和bzoj 1492差不多,只是上凸壳变成下凸壳了,详见https://www.cnblogs.com/lokiii/p/9199587.html

注意!!转移的时候不是f[i]而是f[a[i].id]!!!我简直zz……

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const long long N=500005,inf=1e18;
long long n,s[N],m,dz,f[N];
struct dian
{
double x,y;
bool operator < (const dian &b) const
{
return (x<=b.x)||(x==b.x&&y<=b.y);
}
}p[N],q[N];
struct qwe
{
long long st,sf,k,id;
}a[N],b[N];
bool cmp(const qwe &a,const qwe &b)
{
return a.k<b.k;
}
long long read()
{
long long r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
double wk(long long i,long long j)
{
return (p[i].y-p[j].y)/(p[i].x-p[j].x);
}
void cdq(long long l,long long r)
{
if(l==r)
{
f[l]=min(f[l],(long long)(dz+a[l].st*a[l].sf));
p[l].x=a[l].sf;
p[l].y=f[l];
return;
}
long long mid=(l+r)>>1,top=0,l1=l,l2=mid+1;
for(long long i=l;i<=r;i++)
{
if(a[i].id<=mid)
b[l1++]=a[i];
else
b[l2++]=a[i];
}
for(long long i=l;i<=r;i++)
a[i]=b[i];
cdq(l,mid);
for(long long i=l;i<=mid;i++)
{
while(top>1&&wk(i,s[top])<wk(s[top],s[top-1]))
top--;
s[++top]=i;
}//cerr<<top<<endl;
for(long long i=mid+1,j=1;i<=r;i++)
{
while(j<top&&wk(s[j+1],s[j])<(double)a[i].k)
j++;//cerr<<i<<" "<<s[j]<<endl;
f[a[i].id]=min(f[a[i].id],(long long)(p[s[j]].y+dz+a[i].st*a[i].sf-p[s[j]].x*(m+a[i].st)));
}
cdq(mid+1,r);
l1=l,l2=mid+1;
for(long long i=l;i<=r;i++)
{
if((p[l1]<p[l2]||l2>r)&&l1<=mid)
q[i]=p[l1++];
else
q[i]=p[l2++];
}
for(long long i=l;i<=r;i++)
p[i]=q[i];
}
int main()
{
n=read(),m=read();
for(long long i=1;i<=n;i++)
a[i].st=a[i-1].st+read(),a[i].sf=a[i-1].sf+read(),a[i].k=m+a[i].st,a[i].id=i;
dz=m*a[n].sf;//cerr<<dz<<"!"<<endl;
sort(a+1,a+1+n,cmp);
for(long long i=1;i<=n;i++)
f[i]=inf;
cdq(1,n);
// for(int i=1;i<=n;i++)
// cerr<<f[i]<<endl;
printf("%lld\n",f[n]);
return 0;
}

最新文章

  1. 8种效果实例-jQuery anoSlide 焦点图轮播
  2. 最火的.NET开源项目
  3. JavaScript基础知识(1)
  4. DOM---documentFragment
  5. Another Array of Orz Pandas
  6. jquery 封装
  7. 【Python】随机模块random &amp; 日期时间のtime&amp;&amp;datetime
  8. oracle 导入/导出遇到的 问题总结
  9. c# 用户自定义转换
  10. 基于CRM跟进(活动)记录中关键字识别的客户跟进加权值的成单概率算法
  11. zabbix3.2监控redis
  12. WebClient 支持 gzip, deflate
  13. 【Storm】Storm实战之频繁二项集挖掘(附源码)
  14. Golang闭包入门了解
  15. 牛逼的lsof命令!!!
  16. 【Py大法系列--01】20多行代码生成你的微信聊天机器人
  17. objc单例的两种安全实现方案
  18. 【ZJ选讲&#183;BZOJ 5073】
  19. Django 四——ModelForm用法
  20. ubuntu18.04中mysql的安装及远程连接配置

热门文章

  1. java成员变量
  2. 测试各种低价VPS
  3. 权限管理组件:rbac
  4. Linux下汇编语言学习笔记1 ---
  5. codeforces 691F(组合数计算)
  6. Minimum Path Sum(DFS,DP)
  7. Servlet的服务端响应
  8. 我的arcgis培训照片4 来自http://www.cioiot.com/successview-549-1.html
  9. 001 Cisco router prewired
  10. 魔兽争霸3 冰封王座 w3g文件如何打开