UVA 11020 Multiset应用

本文介绍了一种用于在线维护二维平面上点集合的算法,并通过C++实现。该算法能够高效地处理点的插入操作,同时确保集合中不存在优势点,即不存在另一个点在两个坐标轴上都比当前点小的情况。每插入一个新点后都会输出当前集合中的点数。

点击打开链接

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <set>
using namespace std;
const int M =15010;
struct Point{
	int x;
	int y;
	bool operator<(const Point& t)const {
		return  x<t.x|| (x==t.x && y<t.y); //对x从小到大排序,x相等时按y从小到大排序 
	}
};
multiset<Point> S;
multiset<Point>::iterator it;


int main()
{
	int t;
	cin>>t;
	for(int i=1;i<=t;i++)
	{
		if(i>1) cout<<endl;
		int n;
		cin>>n;
		S.clear();
		printf("Case #%d:\n",i); 
		
		
		while(n--)
		{
			int a,b;
			cin>>a>>b;
			Point P={a,b};
			it=S.lower_bound(P);//找到第一个  x大于等于px的元素 
			
			if(it==S.begin()||(--it)->y>b)// px>x py<y则p有优势 
			{
				S.insert(P);
				//p插入后 淘汰掉一些没有优势的点
				it=S.upper_bound(P);
				while(it!=S.end()&& it->y>=b)
				{
					S.erase(it++);	
				} 
			} 
			cout<<S.size()<<endl;
		}
	}
	return 0;	
} 


### Multiset 数据结构实现和用法 #### 定义与特性 `std::multiset` 是 C++ 标准模板库 (STL) 提供的一种关联容器,其内部采用红黑树(一种自平衡二叉查找树)作为底层数据结构[^2]。这种设计确保了 `multiset` 能够高效地支持插入、删除以及查找操作。 #### 关键属性 - **允许重复元素**:不同于 `set` 只能保存唯一值,`multiset` 支持同一数值多次出现。 - **自动排序功能**:所有成员函数均保持集合有序排列,默认按升序组织;可通过定制比较器改变顺序逻辑。 #### 自定义类型的支持 对于复杂的数据类型如结构体或类对象,为了能够在 `multiset` 中正常工作并维持特定次序关系,需重载小于运算符 (`<`) 或者提供外部比较谓词给定构造参数。例如,在给出的例子中: ```cpp struct rec { int x, y; }; struct cmp { bool operator()(const rec& a, const rec& b) const { return a.x < b.x || (a.x == b.x && a.y < b.y); } }; ``` 这里定义了一个名为 `rec` 的简单记录类型及其对应的比较规则 `cmp`,之后可以创建基于此类型的多集实例: ```cpp #include <set> // ... multiset<rec, cmp> h; ``` 上述代码片段展示了如何利用用户定义的比较方式初始化一个多集中存储 `rec` 类型的对象,并依据指定条件进行排序[^1]。 #### 基本操作方法概览 - 插入新项:使用 `insert()` 成员函数向容器添加元素; - 删除现有条目:调用 `erase()` 方法移除单个或者全部匹配项; - 查找目标位置:借助迭代器遍历访问各节点,亦可运用 `find()` 函数快速定位某关键字所在之处; - 获取大小统计:通过 `size()` 查询当前容纳了多少实体单元。 综上所述,`multiset` 不仅继承了标准关联容器的优势特点——即高效的检索性能及稳定的内存管理机制,还进一步放宽了关于唯一性的约束限制,使之成为处理含有冗余信息场景下的理想选择之一。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值