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
",Ans);
}
原文地址:https://www.cnblogs.com/SiriusRen/p/6908839.html