zoukankan      html  css  js  c++  java
  • 题解 CF535E 【Tavas and Pashmaks】

    首先可得到这个式子:

    (frac{A}{a_{i}}+frac{B}{b_{i}}=T​)

    其中 (T​) 表示时间,这个式子应该不难理解,题目就转换成了对于一对 ((a_{i}​) , (b_{i})​) ,如果存在一对 ((A,B)​) 使得时间 (T​)((a_{i}​) , (b_{i})​) 上最小,就输出。
    接下来是做法:
    考虑把 ((frac{1}{a_{i}}​) , (frac{1}{b_{i}})​) 看做平面上的点,原式变成 (Ax+By=T​) ,这就是你们喜欢的一次函数啦。继续把原式变得更通俗

    (y=-frac{A}{B}x+frac{T}{B}​)

    由于点 ((x,y)​) 是给定的,假设你已经确定直线的斜率,也就是 (-frac{A}{B}​) ,你就可以算出时间 (T​) ,进而轻松地确定哪对点是答案。
    那么,怎么确定斜率呢?我们可以通过画图发现,是答案的点一定在平面图的左下凸包上,如果明白凸包的思想,
    那么问题就很简单了,至于没学过凸包的同学,可以参考yyb的博客这篇博客没学凸包还想做此题?),蒟蒻我就不多说了qwq
    如果看懂了上述内容但不懂凸包过程,请转

    上代码:

    #include<bits/stdc++.h>
    #define ll long long
    #define ld long double 
    using namespace std;
    inline ll read(){
        ll f=1,w=0;char x=0;
        while(!(x>='0'&&x<='9'))
        {
            x=getchar();
            if(x=='-') f=-1;
        }
        while(x>='0'&&x<='9')
        {
            w=(w<<3)+(w<<1)+(x^48);
            x=getchar();
        }
        return f*w;
    }//习惯性的快读
    struct people{
        ll a,b,id;
    }p[300010];
    ll n,s[300010],t;
    bool v[300010],ans[300010];
    bool cmp(people a,people b){
        if(a.a==b.a) return a.b>b.b;
        return a.a>b.a;
    }//凸包排序
    ld check(people a,people b){
        return (ld)a.a*b.a*(b.b-a.b)/(b.a-a.a)/b.b/a.b;
    }//斜率的计算
    int main(){
        n=read();
        for(int i=1;i<=n;i++) p[i].a=read(),p[i].b=read(),p[i].id=i;
        sort(p+1,p+n+1,cmp);
        s[1]=1,t=1;
        ll maxb=p[1].b;
        for(int i=2;i<=n;i++)
            if(p[i].b<=maxb) v[i]=1;
            else maxb=p[i].b;
        //去重和排除能一眼看出非答案的点,譬如a和b都比另一个点小
        for(int i=2;i<=n;i++)
        {
            if(v[i]||check(p[i],p[s[t]])>0) continue;//斜率大于0排除
            while(t>1&&check(p[i],p[s[t]])<check(p[s[t-1]],p[s[t]]))
                t--;
            s[++t]=i;
        }//单调栈维护的类似于凸包的过程
        for(int i=1;i<=t;i++)
        {
            ans[p[s[i]].id]=1;
            for(int j=s[i]+1;j<=n&&p[s[i]].a==p[j].a&&p[s[i]].b==p[j].b;j++)
                ans[p[j].id]=1;
        }//还原位置相同的点
        for(int i=1;i<=n;i++)
            if(ans[i]) cout<<i<<" ";
        return 0;
    }
    
  • 相关阅读:
    关于Vue修改默认的build文件存放的dist路径
    JSON.stringify的三个参数(转载)
    JS获取字符串实际长度(包含汉字)的简单方法
    JSON.stringify() 和 JSON.parse()
    iPhone各种机型尺寸、屏幕分辨率
    jquery each 遍历
    React 內联式样
    组件Refs(操作DOM的2⃣️两种方法)
    可复用组件
    事件与数据的双向绑定
  • 原文地址:https://www.cnblogs.com/ajy-shi-cj-zui-cai/p/10386720.html
Copyright © 2011-2022 走看看