UVA 11020 Efficient Solutions+multiset的应用

题目链接:点击进入
首先来讲,非常easy看到我们事实上仅仅要维护优势人群的集合;假设增加一个新的人,我们首先看一下优势人群中是否有人会让这个人失去优势,假设没有,则将这个人插入集合中。但要注意到这个人的插入可能会让其他的人失去优势。所以要求这个集合要能支持高速查询和改动操作。而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("
");
        printf("Case #%d:
",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
",S.size());
        }
    }
  return 0;
}
原文地址:https://www.cnblogs.com/cynchanpin/p/7066844.html