膜IOI爷的题解
凸包上三分。。
#include<iostream>
#include<cstdio>
#define N 100105
using namespace std;
int n,top,stack[N];
double d;
double sum[N],x[N];
struct node {double x,y;} a[N];
double cross(node a,node b,node c)
{
return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
}
double slop(node a,node b)
{
return (a.y-b.y)/(a.x-b.x);
}
double find(node t)
{
int l=1,r=top,lmid,rmid;
while (r-l>=3)
{
lmid=l+(r-l)/3;
rmid=r-(r-l)/3;
double K1=slop(a[stack[lmid]],t),K2=slop(a[stack[rmid]],t);
if (K1<K2) l=lmid; else r=rmid;
}
double ans=0.0;
for (int i=l;i<=r;i++) ans=max(ans,slop(a[stack[i]],t));
return ans;
}
int main()
{
scanf("%d%lf",&n,&d);
for (int i=1;i<=n;i++)
{
scanf("%lf%lf",&sum[i],&x[i]);
sum[i]+=sum[i-1];
a[i]=(node){i*d,sum[i-1]};
}
double ans=0;
for (int i=1;i<=n;i++)
{
while (top>1&&cross(a[i],a[stack[top]],a[stack[top-1]])>=0) top--;
stack[++top]=i;
node q=(node){x[i]+i*d,sum[i]};
ans+=find(q);
}
printf("%.0lf\n",ans);
return 0;
}