set

底层实现是用红黑树。

set 建立

set<int> s; // 不可重,默认升序
set<int,less> s; // 不可重,升序
set<int,greater> s; // 不可重,降序
multiset<int> s; // 可重集

set 也可以重载,利用结构体实现。

重载方式同 priority_queue 。

set 插入及访问

set<int>::iterator it;
s.insert(x); // 插入元素 x
s.begin(); // 最前面的迭代器
s.end(); // 最后一个元素之后的迭代器(实则空)
s.rbegin(); // 最后一个迭代器
s.rend(); // 最前面的前一个迭代器 pair<set<int>::iterator,bool> it=s.insert(x);
if(it.second) { 插入成功 }
else { 插入失败 }

set 大小

s.size(); //返回容器中元素的数目
s.empty(); //判断容器是否为空

set 的删除操作

s.clear(); //清除所有元素
s.erase(it); //删除 it 迭代器所指的元素,返回下一个元素的迭代器。
s.erase(l,r); //删除区间 [l,r) 的所有元素,返回下一个元素的迭代器。
s.erase(x); //删除容器中值为 x 的元素。

有的时候为了避免删除一个空的位置,在删除是可以采用以下操作:

s.erase(s.find(*it));

set 的查找操作

s.find(x); //查找 x 元素,返回指向 x 元素的迭代器。
s.count(x); //返回容器中值为 x 的元素个数。对 set 来说,要么是 0,要么是 1。对 multiset 来说,值可能大于 1。
s.lower_bound(x); //返回第一个 >=x 元素的迭代器
s.upper_bound(x); // 返回第一个 >x 元素的迭代器。
s.equal_range(x); //返回容器中与 x 相等的上下限的两个迭代器。上限是闭区间,下限是开区间,如 [l,r) 。

例题

P1081 [NOIP2012 提高组] 开车旅行

用 \(\text{set}\) 维护的部分:

给定数列 \(\{h\}\) (\(h_i\) 互不相同),定义两点 \(i,j(i<j)\) ,它们间的距离 \(dist(i,j)\) 为 \(abs(h[i]-h[j])\) 。

对于每个 \(i\) ,求出距离 \(i\) 最近、次近的 \(j(j>i)\) (若距离一致,\(h\) 越小的 \(j\) 距离 \(i\) 更近)。

考虑用 set 与 lower_bound 实现。

由于最后的几个数找不到相应的答案,因此要在 set 中提前加入极大、极小的值。

每次查询 \(i\) 时,查出比 \(h[i]\) 小的最大编号,再访问其向前、向后的迭代器即可。

部分代码
h[0]=inf,h[n+1]=-inf;
st.insert((Data){inf,0}),st.insert((Data){inf,0});
st.insert((Data){-inf,n+1}),st.insert((Data){inf,n+1});
for(int i=n;i;i--)
{
int ga,gb; // ga:max_max gb:max_min
st.insert((Data){h[i],i});
set<Data>::iterator it=st.lower_bound((Data){h[i],i});
it--;
int ln=(*it).num,lh=(*it).val;
it++,it++;
int rn=(*it).num,rh=(*it).val;
it--;
if(abs(lh-h[i])<=abs(rh-h[i]))
{
gb=ln,it--,it--;
if(abs(h[i]-(*it).val)<=abs(rh-h[i])) ga=(*it).num;
else ga=rn;
}
else
{
gb=rn,it++,it++;
if(abs(h[i]-(*it).val)>=abs(lh-h[i])) ga=ln;
else ga=(*it).num;
}
fa[0][i][0]=ga;
fa[0][i][1]=gb;
}

priority_queue

应用——对顶堆

维护

void tosame(int size_l)
{
while(qmin.size()<siz_l) qmin.push(qmax.top()),qmax.pop();
while(qmin.size()>siz_l) qmax.push(qmin.top()),qmin.pop();
} void check()
{
while(qmin.top()>qmax.top())
{
qmin.pop(),qmin.push(y);
qmax.pop(),qmax.push(x);
}
}

例题

P3644 [APIO2015]八邻旁之桥

给出 \(2n\) 个点,我们需要挑 \(1\) 个点,使得这 \(2n\) 个点到该点的距离和最小。

先考虑 \(k=1\) 的情况,这其实是一个很经典的结论,最优位置显然在中位数处(即排序后第 \(N\) 个点和第 \(N+1\) 个点之间的任意一点)取得。

接下来是 \(K=2\) 的情况。此时集合点变成了两个,画图后会发现,对于一条线段 \(AB\) 而言,选择离这个线段中点较近的集合点结果最优。

考虑将所有线段按 \(s_i+t_i\) 的顺序排序,枚举区域分界点,则分界点左边的区域前往左侧集合点,右边的区域前往右侧集合点,问题变成了 \(K=1\) 的情况。

设集合大小为 \(s\),我们维护一个大根堆,存放前 \(\dfrac{s}{2}\) 小的元素,再维护一个小根堆,存放后 \(\dfrac{s}{2}\) 小的元素,则中位数为两堆的堆顶(任取其一即可)。

代码

include

reverse 翻转

翻转一个 vector

reverse(a.begin(),a.end());

翻转一个数组:

reverse(a+1,a+n+1);

unique 去重

unique 用于“去除”容器中相邻的重复元素(将重复的放在容器末尾),并返回去重后的尾地址。

由于去除的是相邻的元素,一般将容器排好序后去重。

例如:

int a[10]={1,1,2,2,2,3,3,4,5,5};
int ans=unique(a,a+10)-a;

则 \(ans\) 的值为 \(5\) 。

vector 去重同理:

int m=unique(a.begin(),a.end())-a.begin();

rand_shuffle 随机打乱

用法同 reverse ,经常在模拟退火与爬山算法中使用。

next_permutation 下一个排列

若存在下一个排列,则返回值为 true ,否则为 false

lower_bound/upper_bound 二分

指定部分应该是排好序的!

lower_bound 返回第一个大于等于 \(x\) 的元素的迭代器。

upper_bound 第一个大于 \(x\) 的元素的迭代器。

例如:

查找 int 数组中大于等于 \(x\) 的最小整数下标:

int i=lower_bound(a+1,a+n+1,x)-a;

vector 中查找小于等于 \(x\) 的最大整数(假设存在):

int i=*--upper_bound(a.begin(),a.end(),x);

C++STL(set……)的更多相关文章

  1. 使用VS2012编译和使用C++ STL(STLport)

    使用VS2012编译和使用C++ STL(STLport) http://cstriker1407.info/blog/use-vs2012-to-compile-and-use-the-c-stl- ...

  2. [转贴]从零开始学C++之STL(一):STL六大组件简介

    一.STL简介 (一).泛型程序设计 泛型编程(generic programming) 将程序写得尽可能通用 将算法从数据结构中抽象出来,成为通用的 C++的模板为泛型程序设计奠定了关键的基础 (二 ...

  3. C++STL(二)——vector容器

    STL--vector容器 vector对象的概念 vector基本操作 vector对象的初始化.赋值 vector查找.替换(已在上一片 string类 博客总结过了,不再总结) vector添加 ...

  4. STL(六)——map、multimap

    STL--map.multimap 文章目录 STL--map.multimap 关联容器与map的介绍 map与set的异同 map与multimap的异同 map类对象的构造 map添加元素 ma ...

  5. C++学习之STL(一)vector

    前言 C++ Primer Plus读书笔记(三)复合类型 中已经简单介绍过vector是什么,这个系列主要是介绍STL特性. 声明 vector<ElemType> c; //创建一个空 ...

  6. 从零开始学C++之STL(七):剩下5种算法代码分析与使用示例(remove 、rotate 、sort、lower_bound、accumulate)

    一.移除性算法 (remove)  C++ Code  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ...

  7. 51 nod 1624 取余最长路 思路:前缀和 + STL(set)二分查找

    题目: 写这题花了我一上午时间. 下面是本人(zhangjiuding)的思考过程: 首先想到的是三行,每一行一定要走到. 大概是这样一张图 每一行长度最少为1.即第一行(i -1) >= 1, ...

  8. STL(1)

    这一篇因为游戏设计而写的,里面采用了STL,先借用一下,过段时间专项研究. 模板 模板就是一种通用化的类,同一种模板可以创建无数种具有共同特征的容器类型.首先需要指定基础类型,比如int ,char, ...

  9. ACM竞赛常用STL(二)之STL--algorithm

    <algorithm>无疑是STL 中最大的一个头文件,它是由一大堆模板函数组成的.下面列举出<algorithm>中的模板函数: adjacent_find / binary ...

  10. ACM竞赛常用STL(一)

    全排列函数next_permutation STL 中专门用于排列的函数(可以处理存在重复数据集的排列问题) 头文件:#include <algorithm> using namespac ...

随机推荐

  1. 关于JDK高版本下RMI、LDAP+JNDI bypass的一点笔记

    1.关于RMI 只启用RMI服务时,这时候RMI客户端能够去打服务端,有两种情况,第一种就是利用服务端本地的gadget,具体要看服务端pom.xml文件 比如yso中yso工具中已经集合了很多gad ...

  2. 一起学习PHP中GD库的使用(二)

    在日常的开发过程中,GD 库最常用的功能就是帮我们对图片进行一些处理,当然,除了处理已有的图片之外,它也可以直接来画图,就像我们最常见的图片验证码.今天的内容主要就是和画图有关,所以最后我们也会做一个 ...

  3. goto语法在PHP中的使用

    在C++.Java及很多语言中,都存在着一个神奇的语法,就是goto.顾名思义,它的使用是直接去到某个地方.从来代码的角度来说,也就是直接跳转到指定的地方.我们的PHP中也有这个功能,我们先来看看它是 ...

  4. 使用metaweblog API实现通用博客发布 之 本地图片自动上传以及替换路径

    使用metaweblog API实现通用博客发布 之 本地图片自动上传以及替换路径 通过metaweblog API 发布博文的时候,由于markdown中的图片路径是本地路径,将导致发布的文章图片不 ...

  5. vue跳转路由

    1.  router-link 1. 不带参数 <router-link :to="{name:'home'}"> <router-link :to=" ...

  6. TP5多条件搜索,同时有必要条件

    $model = $this->model; // 查询是否有搜索参数 $search = input('?get.search') ? trim(input('get.search')) : ...

  7. Java面向对象系列(2)- 回顾方法的定义

    方法的定义 修饰符 返回类型 break:跳出switch,结束循环和return的区别 方法名:注意规范,见名知意 参数列表:(参数类型,参数名) 异常抛出 package oop.demo01; ...

  8. requests接口自动化-列表与字典参数化

    def server_ip(): # 配置文件,通过修改配置,在不同环境进行测试 # dev_ip='https://www.baidu.com/' # sit_ip='https://cn.bing ...

  9. 鸿蒙内核源码分析(调度机制篇) | 任务是如何被调度执行的 | 百篇博客分析OpenHarmony源码 | v7.07

    百篇博客系列篇.本篇为: v07.xx 鸿蒙内核源码分析(调度机制篇) | 任务是如何被调度执行的 | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调 ...

  10. P6091-[模板]原根

    正题 题目链接:https://www.luogu.com.cn/problem/P6091 题目大意 给出一个数\(p\),求出它的所有在\([0,p]\)的原根. 解题思路 原根的定义,\(\de ...