zoukankan      html  css  js  c++  java
  • CodeForces 749D Leaving Auction

    二分查找,$set$。

    对于某一次询问,如果把人删光了,那么输出$0$ $0$。

    如果只剩下$1$个人,那么输出那个人喊的最低价格。

    如果剩下的人数有大于等于两个,

    这时最底下出现的情景必然是红色部分由一个人喊,紫色部分由另一个人喊。

    这两个人分别是喊价最高价次高者和最高者,并且红色部分最后一个位置的下一个位置就是答案。因此只需在获取两个人的信息后,在最高者喊价序列中二分即可。

    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    #include<iostream>
    #include<set>
    using namespace std;
    
    const int maxn=200010;
    int n,q;
    
    struct X
    {
        int id,val;
    }s[maxn];
    
    struct XX{
        int a,b;
        XX () { }
        XX(int A,int B)
        {
            a=A;
            b=B;
        }
    
        bool operator < (const XX &aa) const
        {
            return b>aa.b;
        }
    };
    
    XX fir,sec;
    
    vector<int> v[maxn];
    set<XX> h;
    
    int tmp[maxn],mn[maxn],mx[maxn];
    
    bool check(int x)
    {
        int tt=v[fir.a][x];
        if(s[tt].val<sec.b) return 0;
        return 1;
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=200000;i++) mx[i]=0,mn[i]=2000000000;
    
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&s[i].id,&s[i].val);
            v[s[i].id].push_back(i);
            mx[s[i].id]=max(mx[s[i].id],s[i].val);
            mn[s[i].id]=min(mn[s[i].id],s[i].val);
        }
    
        for(int i=1;i<=200000;i++)
        {
            if(mx[i]==0) continue;
            h.insert(XX(i,mx[i]));
        }
    
        scanf("%d",&q);
        for(int i=1;i<=q;i++)
        {
            int k; scanf("%d",&k);
            for(int j=1;j<=k;j++) scanf("%d",&tmp[j]);
            for(int j=1;j<=k;j++)
            {
                if(mx[tmp[j]]==0) continue;
                h.erase(XX(tmp[j],mx[tmp[j]]));
            }
    
            if(h.size()==0)
            {
                printf("0 0
    ");
            }
            else if(h.size()==1)
            {
                XX ans = *h.begin();
                printf("%d %d
    ",ans.a,mn[ans.a]);
            }
            else
            {
                set<XX>::iterator iter;
                int cnt=0;
    
                for(iter = h.begin() ; iter != h.end(); iter++)
                {
                    cnt++;
                    if(cnt==1) fir = *iter;
                    else if(cnt==2)  {  sec = *iter; break;  }
                }
    
                int L=0,R=v[fir.a].size()-1;
                int ans;
    
                while(L<=R)
                {
                    int mid=(L+R)/2;
                    if(check(mid)) ans=mid,R=mid-1;
                    else L=mid+1;
                }
    
                int tt=v[fir.a][ans];
                printf("%d %d
    ",s[tt].id,s[tt].val);
    
            }
    
            for(int j=1;j<=k;j++)
            {
                if(mx[tmp[j]]==0) continue;
                h.insert(XX(tmp[j],mx[tmp[j]]));
            }
        }
        return 0;
    }
  • 相关阅读:
    在LINUX中 用Ctrl+z挂起的命令怎么切回到原任务的命令窗口
    Linux cat 命令
    关于awk中NR、FNR、NF、$NF、FS、OFS的说明
    Linux如何在vim里搜索关键字
    Social Infrastructure Information Systems Division, Hitachi Programming Contest 2020 D题题解
    AGC043 B题题解
    Social Infrastructure Information Systems Division, Hitachi Programming Contest 2020 C题题解
    JOISC2020 自闭记
    Dwango Programming Contest 6th E 题解
    CF1320 Div1 D.Reachable Strings 题解
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6224661.html
Copyright © 2011-2022 走看看