STL之set

\(STL\)大法好

set

闲话不多说,在神奇的\(STL\)库里面,有一个非常非常好用而且强的\(STL\)\(set\),内部实现是一棵平衡树。它神奇的地方就在于可以对插入、删除、查找在\(O(logn)\)的时间复杂度内实现,并且相当于维护了一个有序序列。\(set\)内部没有重复的元素,而\(multiset\)内部可以有重复的元素。下面介绍几个常用操作。

定义

#include<set>
...
set<int> s;

插入

s.insert(x)表示将值为x的元素插入set中,set会维护有序序列

删除

s.erase(x)表示删除值为x的元素

s.erase(it)表示删除指针为it的元素

s.erase(x);
与
set<int>::iterator it=s.find(x);
if(it!=s.end()) s.erase(it);
等效(multiset中不是

要注意的是,第一个删除会所有值为\(x\)的元素,而第二个删除只会删除一个。对于\(set\)而言,这两种操作没有任何区别。但对于\(multiset\),就要看情况选择删除全部还是删除\(1\)个。

查找

s.find(x)表示查询值为x的位置,会返回x的指针。如果不存在该元素会返回x.end()

set<int>::iterator it=s.begin();
*it即为最大元素

set<int>::iterator it=--s.end();
*it即为最小元素

二分

s.lower_bound(x)即为查找大于等于x的第一个数的指针

s.upper_bound(x)即为查找大于x的第一个数的指针

可以用于查找前驱后继

遍历

set<int> s;
for(int i=1;i<=n;i++) s.insert(a[i]);
for(set<int>::iterator it=s.begin();it!=s.end();it++) cout<<*it<<endl;

学长出的例题

思路

首先前六个操作都是白给。插入删除,前驱后继,最大最小,用上述函数即可。而对于操作七,考虑维护一个全局加变量。每次插入时将插入的\(x\)减去全局加变量加到\(multiset\)中,然后每次取出的时候再加上全局加变量输出就可以了。而且要注意二分求前驱后继的时候也要查询\(x-add\)

代码

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<set>
#define ll long long
using namespace std;
int q;
ll las,add,op,x;
multiset<ll> s;
int main()
{
	scanf("%d",&q);
	for(int i=1;i<=q;i++){
		scanf("%lld",&op);
		op=op ^ las;
		if(op==1){
			scanf("%lld",&x);
			x-=add;
			s.insert(x);
		}
		if(op==2){
			scanf("%lld",&x);
			multiset<ll>::iterator it=s.find(x-add);
			if(it!=s.end()){
				s.erase(it);
			}
		}
		if(op==3){
			if(!s.size()){
				printf("zay\n");
			}
			else{
				multiset<ll>::iterator it=--s.end();
				las=*it+add;
				printf("%lld\n",las);
			}
		}
		if(op==4){
			if(!s.size()){
				printf("zay\n");
			}
			else{
				multiset<ll>::iterator it=s.begin();
				las=*it+add;
				printf("%lld\n",las);
			}
		}
		if(op==5){
			scanf("%lld",&x);
			multiset<ll>::iterator it=s.lower_bound(x-add);
			if(it==s.begin()){
				printf("cuc\n");
			}
			else{
				it--;
				las=*it+add;
				printf("%lld\n",las);
				
			}
		}
		if(op==6){
			scanf("%lld",&x);
			multiset<ll>::iterator it=s.upper_bound(x-add);
			if(it==s.end()){
				printf("cyc\n");
			}
			else{
				las=*it+add;
				printf("%lld\n",las);
				
			}
		}
		if(op==7){
			scanf("%lld",&x);
			add+=x;
		}
	}
	return 0;
}
posted @ 2020-12-27 14:34  徐明拯  阅读(139)  评论(0编辑  收藏  举报