priority_queue

最常用的当然是在dij的时候.

#include <queue>

struct node {
int x, dis;
bool operator < (const node a) const { return a.dis < dis; }
//需要注意的是这个地方要反着写,一定要反着写,也就是平常打cmp时的dis<a.dis改成a.dis<dis
//然后在node a前面加上一个const }; priority_queue<node> Q;

当然,这里有很多种打法,我现在习惯于用下面这种,不用去记那些什么const麻烦:

struct node {
int x, dis;
friend bool operator (node x, node y) { return x.dis < y.dis; }
} priority_queue <node> Q;
  • Q.top().x就是每次堆顶的元素了。
Dijkstra这样打:
priority_queue <node> Q; Q.push({i, 0}), mem(vis, 0), mem(dis, 7), dis[i] = 0;
while (Q.size()) {
k = Q.top().x; Q.pop();
if (vis[k]) continue; vis[k] = 1;
for (x = las[k] ; x ; x = nex[x])
if (dis[tov[x]] > dis[k] + 1)
dis[tov[x]] = dis[k] + 1, Q.push({tov[x], dis[tov[x]]});
}

虽然priority_queue没有set那么好用,但毕竟set存不了实数,所以有时候优先队列也是略胜一筹的。

它还有这些基本操作:

priority_queue<int> Q; //这样就定义了一个优先队列
priority_queue<double> Q; //这样也可以
priority_queue<node> Q; // 存储一个结构体,例如像上面的dijkstra时的结构体。 //但如果不用结构体,我们可以这样子打,在定义的时候确定运算符:
priority_queue<int, vector<int>, less<int> > Q; //这样是从大到小的,也是C++默认的
priority_queue<int, vector<int>, greater<int> >Q; //这样是从小到大的

注意 vector<int>以及后面的> >不要连起来.

和普通队列一样,它有这些基本操作:
q.size();//返回q里元素个数
q.empty();//返回q是否为空,空则返回1,否则返回0
q.push(k);//在q的末尾插入k
q.pop();//删掉q的第一个元素 ---这个操作最重要。。。。
q.top();//返回q的第一个元素

bitset

  • bitset用来压位,使复杂度在原来的基础上除以\(32\).
#include <bitset>

bitset<N> S; //这样就可以建一个bitset了

S.set(); //全部变成1
S.reset(); //全部变成0 S.count(); // 返回1的个数
S.flip(); // 把S每一位都取反
S.flip(i); //仅把第i为取反 S.any(); //返回是否有1
S.none(); //返回是否没有1 ///表示并不知道这个看似牛逼的操作有什么用
a.to_ulong() //转成一个unsigned long long的数. //bitset支持位运算操作,非常强大. 如 a = a & b; a = a ^ b; a = a | b;

还需要注意的是,bitset支持左移、右移操作,得到一个新的bitset

具体的,这个操作可以用在一些形如\(f_x=or_{f_{x+km}}\)的操作上,详细见:https://jzoj.net/senior/#main/show/6123 这道题的DP优化。

vector

表示vector是个既能装逼,又实用的东西,但请注意: vector常数巨大,一般如果是存边的话,尽量用邻接表或者前向星.

#include <vector>

vector <int> d,a[N]; //都可以定义

d.push_back(x) //在d这个vector里面插入一个x元素,注意,相当于数组的插入.

printf("%d", d[i]) //询问插入的第i个元素,注意下标从0开始
printf("%d", d.size() - 1) //返回插入元素个数
d.front(); d.back(); //第一个,最后一个元素,好吧实际上没有用
d.clear(); //清空 把d排序:sort(d.begin(), d.end());
struct node {
int u, dis;
bool operaotr < (node x) const { return dis < x.dis; }
}
当然,也可以定义结构体vector<node>,然后按上面的一样排序就可以了. d.insert(d.begin() + k, v) // 表示在第k个位置插入一个元素v,把k+1~d.end()的都往后移一个位置.
//表示并不知道上面这个操作有什么用,并且当k=0时,插入550000个元素,它用了49.007s
//插入100000个元素时,仅用了1.78s int v = upper_bound(d.begin(), d.end(), node{a, b}) - d.begin() - 1;
//与普通的数组的upper_bound是类似的, 只不过有结构体时,需要operator. 注意,upper_bound是返回第一个大于某数的迭代器
lower_bound是返回第一个大于等于某数的迭代器,这两个操作很重要,在set里面也是一样的.

总结一下,vector里面这个upper_bound(a.begin(), a.end(), node{x,y}) - a.begin() - 1这个操作很重要.

然后就是vector虽然方便(比如说打点分树的时候,需要把每一个分治中心带的节点用结构体储存,这时候就超级好用),但是也牺牲了时间,它的常数比较大.

map

map也是一个炒鸡好用的STL。据cold_chair大佬所言,当元素很多的时候,map会变得很慢,或者说常数很大...

#include <map>

map<type1, type2> a; //这样就定义了一个map.

需要注意的是,其中type1表示的是下标的类型,type2则表示的是存储数的类型.

例如map<string, int> a, map<int, int> a...

修改、使用都是类似于:a[type1] = type2

a.erase(type1) // 表示删除某个数
a.clear(); //清空
a.empty(); //判断是否为空
a.size(); //返回a的元素个数

map的用法还是很多的。

注意,一般来说,我们是定义

map <int, int> h;

如果要在某个位置赋值,可以直接调用

h[x] = y;

但注意,因为几乎所有的STL容器我们都只能用

:: iterator it;

来得到位置,所以如果我们要把对应的值求出来,则要用

it -> first 或 it -> seond

两种操作。

最后还需要知道,map的实现是类似于set的,所以他也支持\(log\)的查找最小最大值。

具体来说,我们可以这样调用:

for (map<int,int> :: iterator it = h.begin(); it != h.end(); it ++) {
printf("%d\n",it->first)
H[it->first] = 1;
}

Set

很强大的一个功能。

#include <set>

set <int> a; //这样就建好一个set了
请务必注意:set是不可以支持重复元素的,想要有重复元素,可以使用multiset multiset <int> a; //这是可以支持重复元素插入的。 a.insert(x); //表示在set里面插入一个x元素. a.erase(x); //表示把set里面所有为x的数的删掉.
a.erase(a.find(x)); //这个表示只删除一个x. *a.begin() // 表示最小值
*a.end() // 表示最大值的下一个位置
*--a.end() //表示最大值 // 因为返回的都是一个迭代器,所以具体数值要在前面加一个*号。 可能有时候要多次用到某个迭代器,所以我们可以把他储存下来,用一个it来表示,其中it这样定义: multiset<int> :: iterator it;
//那么像上面的最小值,就可以这样表示it = a.begin(), printf("%d\n", *it). it ++就可以表示下一个位置的元素,当然不要滥用,因为这个++是需要log的时间复杂度的。。 其中,set里面最重要的两个操作就是上面vector里面的两个操作,即lower_bound和upper_bound. it = a.lower_bound(x) //表示找到第一个大于等于x元素的迭代器
it = a.upper_bound(x) //表示找到第一个大于x元素的迭代器

注意,如果合并两个map,我们可以用上面的\(log\)查找 + 对应位置赋值 实现。

但是set可以更方便的写成:

Set1.insert(Set2.begin(),Set2.end());

这样就把Set2插入到Set1中去了。

请注意,\(set\)和\(map\)都可以用来做启发式合并,且常数几乎一模一样。

ctime

  • 测时间的以及随机时候用的.
srand(time(0)) //随机种子,没有这个东西,随机相当于没有随机.

主要想说的是这个:

int st = clock();

// do sth

printf("%lf\n", (double) (clock() - st) / CLOCKS_PER_SEC)

总结

  • wulala~终于把目前所学的一些知识整理了一下.

  • 鉴于自己学识浅薄,就不再多逼什么了.

C++ STL的一些操作的更多相关文章

  1. STL之stack操作

    c++ stl栈stack介绍 C++ Stack(堆栈) 是一个容器类的改编,为程序员提供了堆栈的全部功能,——也就是说实现了一个先进后出(FILO)的数据结构. c++ stl栈stack的头文件 ...

  2. luogu题解P1032字串变换--BFS+STL:string骚操作

    题目链接 https://www.luogu.org/problemnew/show/P1032 分析 这题本来很裸的一个BFS,发现其中的字符串操作好烦啊.然后就翻大佬题解发现用STL中的strin ...

  3. C++ STL string对象操作汇总

    string对象 C语言只提供了一个char类型用来处理字符,而对于字符串,只能通过字符串数组来处理,显得十分不便.C++STL提供了string基本字符系列容器来处理字符串,可以把string理解为 ...

  4. STL之map操作[转]

    转自https://www.cnblogs.com/yutongzhu/p/5884269.html 作者彼得朱 map 是一种有序无重复的关联容器. 关联容器与顺序容器不同,他们的元素是按照关键字来 ...

  5. STL 集合部分操作

    3.28更新 在EOJ 1641 集合栈计算机中,使用并集和补集时候,第五个参数使用x.begin()会报错:assignment of read-only location,而使用inserter( ...

  6. STL string常用操作指令

    s.insert(pos,args); 在pos之前插入args指定的字符.pos可以是一个下标或一个迭代器.接受下标的版本返回一个指向s的引用;接受迭代器的版本返回指向第一个插入字符的迭代器. s. ...

  7. stl(优先队列操作)

    http://codeforces.com/gym/101911/problem/C Recently Monocarp has created his own mini-laboratory! Th ...

  8. STL——heap的4大操作

    STL的堆操作 STL里面的堆操作一般用到的只有4个:make_heap();.pop_heap();.push_heap();.sort_heap(); 他们的头文件函数是#include < ...

  9. 容器使用的12条军规——《Effective+STL中文版》试读

    容器使用的12条军规——<Effective+STL中文版>试读     还 记的自己早年在学校学习c++的时候,老师根本就没有讲STL,导致了自己后来跟人说 起会C++的时候总是被鄙视, ...

随机推荐

  1. Webpack 4教程 - 第七部分 减少打包体积与Tree Shaking

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:https://wanago.io/2018/08/13/webpack-4-course-part ...

  2. WordCount结对编程

    合作者:201631062602,201631062114 代码地址:https://gitee.com/Changyu-Guo/pairing_project 作业链接:https://www.cn ...

  3. HBase单机模式部署

    1.上传&解压 2.设置环境变量 3.启用&检验 4.编辑hbase-env.sh 5.编辑hbase-site.xml 6.启动hbase 7.验证 8.启动hbase shell

  4. javafx--tableView笔记-----tableView里已经填充了实体类数据但是很狗血地显示不出来

    private String cClass private String cUp private String cDown 刚开始实体类的字段 cClassCol.setCellValueFactor ...

  5. [FTP]通过FileZilla在阿里云主机上搭建ftp服务器

    前一阵子租了一台服务器主机来玩,正好周末有时间研究了一下怎么搭建ftp server. 准备.首先要下载filezilla client和filezilla server, 下载地址: server: ...

  6. Linux(CentOS7)下远程拷贝文件,scp命令

    一.Linux版本 二.scp命令 scp [参数] [原路径] [目标路径] scp -P 22022 /home/file.war root@192.168.253.172:/home/test ...

  7. L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到了一个处理错误(转)

    L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到了一个处理错误   错误描述:“ L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到了一个处理错误” 只有这个没有错误码. ...

  8. node+mysql,实现基本的增删改查,附带跟踪记录和运行时间记录

    Node + mysql 实现基础的增删改查,以及性能测试. 网上有很多这样的例子,我也是找来学习的. 感觉node对mysql的操作非常简单,也很实用,比如自带防止sql注入的功能,一开始还担心注入 ...

  9. MySQL操作(备份很重要)

    文档一: --修改用户密码的命令 mysqladmin -uroot -proot123 password mysql123 --登录mysql数据库的命令 mysql -uroot -proot12 ...

  10. 360大牛:全面解读PHP面试

    让大家了解基本面试流程和面试的核心要求以及意义是什么并理解PHP面试考点主要以基础为核心,说明PHP面试考察范围. 有需要联系:QQ:1844912514