UVA 11020 Efficient Solutions+multiset的應用

acm_lkl發表於2020-04-04

題目連結:點選進入
首先來講,很容易看到我們其實只要維護優勢人群的集合;如果加入一個新的人,我們首先看一下優勢人群中是否有人會讓這個人失去優勢,如果沒有,則將這個人插入集合中,但要注意到這個人的插入可能會讓其它的人失去優勢。所以要求這個集合要能支援快速查詢和修改操作;而multiset恰好能能滿足這個需要。
程式碼如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
using namespace std;

struct Point
{
    int a,b;

    ///Set中的元素按x進行排序
    bool operator <(const Point& rhs) const
    {
          return a<rhs.a||(a==rhs.a&&b<rhs.b);
    }
};

multiset<Point>S;
multiset<Point>::iterator it;

int main()
{
    //freopen("in.txt","r",stdin);
    int T;
    scanf("%d",&T);
    for(int Case=1;Case<=T;Case++)
    {
        if(Case!=1)
          printf("\n");
        printf("Case #%d:\n",Case);

        int n,a,b;
        scanf("%d",&n);
        S.clear();

        while(n--)
        {
            scanf("%d%d",&a,&b);
            Point P=(Point){a,b};
            it = S.lower_bound(P); ///在紅黑樹中查詢第一個小於P的元素
            if(it==S.begin()|| (--it)->b >=b ) ///如果P也具有優勢
            {
                S.insert(P);
                it = S.upper_bound(P); ///it以後的元素都會被影響
                while(it!=S.end()&&it->b >=b) S.erase(it++); ///刪除掉失去優勢的人
            }
            printf("%d\n",S.size());
        }
    }
  return 0;
}

相關文章