CF535E Tavas and Pashmaks

今天Fakehu考的T1。

大致意思就是有n个人每个人有两个速度\(v_1,v_2\),比赛有两个路程\(A,B\),最后时间是\(A/v_1+B/v_2\)。求每个人是否可能成为冠军中的一个。

显然不需要考虑\(A,B\)这两个值,可以钦定\(A=1\)。那么\(t=B/v_2+1/v_1\)。就是一条直线的形式。

然后求一个半平面交就行了。注意这个半平面交是在\(x\geq 0\)部分的。

细节忽略。

#include<bits/stdc++.h>
#define il inline
#define vd void
#define ll long long
#define db long double
il int gi(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return x*f;
}
std::set<std::pair<int,int> >M;
struct yyb{int x,y,i;db k,b;}s[300010],stk[300010];
il bool cmp_k(const yyb&a,const yyb&b){
    if(a.y!=b.y)return a.y<b.y;
    else return a.x>b.x;
}
il bool cmp_i(const yyb&a,const yyb&b){return a.i<b.i;}
int main(){
    int n=gi();
    for(int i=1;i<=n;++i)s[i].x=gi(),s[i].y=gi(),s[i].i=i,s[i].k=1000000000.0/s[i].y,s[i].b=1000000000.0/s[i].x;
    std::sort(s+1,s+n+1,cmp_k);
    int top=0;
    stk[++top]=(yyb){0,0,0,1e18,0};
    for(int i=1;i<=n;++i){
        if(s[i].y==s[i-1].y)continue;
        while(top>1&&stk[top].y!=stk[top-1].y&&(-(s[i].b-stk[top].b)/(s[i].k-stk[top].k)+1e-15<-(stk[top].b-stk[top-1].b)/(stk[top].k-stk[top-1].k)))--top;
        stk[++top]=s[i];
    }
    std::sort(s+1,s+n+1,cmp_i);
    for(int i=1;i<=top;++i)M.insert(std::make_pair(stk[i].x,stk[i].y));
    for(int i=1;i<=n;++i)if(M.find(std::make_pair(s[i].x,s[i].y))!=M.end())printf("%d ",i);
    return 0;
}
posted @ 2018-10-19 16:05  菜狗xzz  阅读(277)  评论(0编辑  收藏  举报