BZOJ 3203 凸包+三分
思路:
iwtwiioi大爷题解:http://www.cnblogs.com/iwtwiioi/p/4007263.html
注意是四舍五入
//By SiriusRen #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=1000500; ll n,d,a[N],X[N],sum[N],top; struct Point{ll x,y;}point[N],q[N],ask; double Ans,ans; Point operator-(Point a,Point b){ Point c;c.x=a.x-b.x,c.y=a.y-b.y;return c; } double cross(Point a,Point b,Point c){ a=a-c,b=b-c;return a.x*b.y-a.y*b.x; } int main(){ scanf("%lld%lld",&n,&d); for(int i=1;i<=n;i++){ scanf("%lld%lld",&a[i],&X[i]); sum[i]=sum[i-1]+a[i]; point[i].x=d*i,point[i].y=sum[i-1]; } for(int i=1;i<=n;i++){ while(top>1&&cross(point[i],q[top],q[top-1])>=0)top--; q[++top]=point[i]; ask.x=X[i]+d*i,ask.y=sum[i]; int l=1,r=top,lmid,rmid; while(r-l>=3){ lmid=l+(r-l)/3,rmid=r-(r-l)/3; double k1=(double)(q[lmid].y-ask.y)/(q[lmid].x-ask.x); double k2=(double)(q[rmid].y-ask.y)/(q[rmid].x-ask.x); if(k2>k1)l=lmid; else r=rmid; }ans=0; for(int i=l;i<=r;i++)ans=max(ans,(double)(q[i].y-ask.y)/(q[i].x-ask.x)); Ans+=ans; } printf("%.0lf\n",Ans); }