[BZOJ 1007] 水平可见直线
Link:
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; }