[BZOJ 1007] 水平可见直线

Link:

BZOJ 1007 传送门

Solution:

维护一次函数凸壳模板

退栈条件为:$top$与$top-1$的交点在$top$与$i$的交点之后

Code:

#include<bits/stdc++.h>

using namespace std;
#define X first
#define Y second
typedef long long ll;
typedef pair<int,int> P;
typedef double db;
const int MAXN=5e5+10;
const db eps=1e-6;
int n,tot,st[MAXN],top;
struct data{db k,b;int id;}dat[MAXN];
bool cmp1(data a,data b)
{
    if(fabs(a.k-b.k)<eps) return a.b>b.b;
    return a.k<b.k;
}
bool cmp2(int x,int y){return dat[x].id<dat[y].id;}
db Cross(int x,int y)
{return (dat[y].b-dat[x].b)/(dat[x].k-dat[y].k);}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%lf%lf",&dat[i].k,&dat[i].b),dat[i].id=i;
    sort(dat+1,dat+n+1,cmp1);
    for(int i=1;i<=n;i++)
        if(fabs(dat[i].k-dat[i-1].k)>eps)
            dat[++tot]=dat[i];
    
    for(int i=1;i<=tot;i++)
    {
        while(top>1&&Cross(i,st[top])<=Cross(st[top-1],st[top])) top--;
        st[++top]=i;
    }
    sort(st+1,st+top+1,cmp2);
    for(int i=1;i<=top;i++)
        printf("%d ",dat[st[i]].id);
    return 0;
}

 

posted @ 2018-09-04 13:46  NewErA  阅读(138)  评论(0编辑  收藏  举报