一开始以为丧尸可以挡伤害,然后发现这个题目的设定非常**
然后就考虑每个丧尸到门口的时间,由于伤害是继承的,所以前缀和分配
然后答案=Σ(HP前缀和*速度/距离) 设 HP/l=k ,l=x+nd 由于后面的点向后和向上的距离一样,所以两点间的斜率一样
HP=k(x+nd)
设Y=HP,X=x+nd ,则要求对一个 点b=0的最大斜率 ,根据上面的结论可以维护上凸包
注意在栈上二分l和r是相反的顺序,注意10^12
码:
#include<iostream>
#include<cstdio>
using namespace std;
int zz,i,ans,l,r,xh[100005];
long long n,d;
double xx[100005],x,y,daan,qsum[100005];
double xl(double x,double y,double xx,double yy)
{
return (y-yy)/(x-xx);
}
int main()
{
scanf("%lld%lld",&n,&d);
for(i=1;i<=n;i++)
{
scanf("%lf%lf",&y,&x);
qsum[i]=qsum[i-1]+y;
while(zz>=2&&xl(x,y,x+(i-xh[zz])*d,qsum[i]-qsum[xh[zz]-1])<=xl(x,y,x+(i-xh[zz-1])*d,qsum[i]-qsum[xh[zz-1]-1]))
zz--;
xh[++zz]=i;
xh[zz+1]=i;
l=1;r=zz;
while(l<r)
{
int mid=(l+r)>>1;
if(xl(0,0,x+(i-xh[mid])*d,qsum[i]-qsum[xh[mid]-1])<xl(x+(i-xh[mid+1])*d,qsum[i]-qsum[xh[mid+1]-1],0,0))
{
l=mid+1;
}else r=mid;
}
daan+=max(xl(0,0,x+(i-xh[l])*d,qsum[i]-qsum[xh[l]-1]),xl(0,0,x+(i-xh[zz])*d,qsum[i]-qsum[xh[zz]-1]));
}
printf("%.0lf",daan);
}