BZOJ3203: [SDOI2013]保护出题人

来源:互联网 发布:淘宝怎么发布虚拟宝贝 编辑:程序博客网 时间:2024/06/05 02:47

BZOJ3203: [SDOI2013]保护出题人

凸包·三分

题解:

http://www.cnblogs.com/iwtwiioi/p/4007263.html

Code:

#include <iostream>#include <cstring>#include <cstdio>#define D(x) cout<<#x<<" = "<<x<<"  "#define E cout<<endlusing namespace std;typedef long long ll;const int N = 100005;struct Point { double x,y; } a[N];ll top, s[N], n, d, x[N], sum[N];double K(Point p1,Point p2){ return (p2.y-p1.y)/(p2.x-p1.x); }double cross(Point a,Point b,Point c) { return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y); }double work(Point p){    ll l=1, r=top, lmid, rmid;    while(r-l>=3){        lmid=l+(r-l)/3;        rmid=r-(r-l)/3;        double k1=K(a[s[lmid]],p), k2=K(a[s[rmid]],p);        if(k2>k1) l=lmid;        else r=rmid;    }    double res=0;    for(ll i=l;i<=r;i++) res=max(K(p,a[s[i]]),res);    return res;}int main(){    freopen("a.in","r",stdin);    scanf("%lld%lld",&n,&d);    for(ll i=1;i<=n;i++){        scanf("%lld%lld",sum+i,x+i);        sum[i]+=sum[i-1];        a[i].x=i*d; a[i].y=sum[i-1];    }    double ans=0;    for(ll i=1;i<=n;i++){        while(top>1 && cross(a[i],a[s[top]],a[s[top-1]])>=0) top--;        s[++top]=i;        Point p; p.x=x[i]+i*d; p.y=sum[i];        ans+=work(p);    }    printf("%.0f\n",ans);}
原创粉丝点击