STL线段树代码库.docx
- 文档编号:6799256
- 上传时间:2023-01-10
- 格式:DOCX
- 页数:30
- 大小:35.99KB
STL线段树代码库.docx
《STL线段树代码库.docx》由会员分享,可在线阅读,更多相关《STL线段树代码库.docx(30页珍藏版)》请在冰豆网上搜索。
STL线段树代码库
STL
| 全排列函数next_permutation
STL 中专门用于排列的函数(可以处理存在重复数据集的排列问题)
头文件:
#include
using namespace std;
调用:
next_permutation(start, end);
注意:
函数要求输入的是一个升序排列的序列的头指针和尾指针.
用法:
// 数组
int a[N];
sort(a, a + N);
next_permutation(a, a + N);
// 向量
vector
sort(ivec.begin(), ivec.end());
next_permutation(ivec.begin(), ivec.end());
例子:
vector
// 初始化代码
sort(myVec.begin(), myVec.end());
do
{
for (i = 0 ; i < size; i ++ ) cout << myVec[i] << " \t " ;
cout << endl;
}
while (next_permutation(myVec.begin(), myVec.end()));
ACM / ICPC 竞赛之STL 简介
一、关于STL
STL(Standard Template Library,标准模板库)是C++ 语言标准中的重
要组成部分。
STL 以模板类和模板函数的形式为程序员提供了各种数据结构和
算法的精巧实现,程序员如果能够充分地利用STL ,可以在代码空间、执行时
间和编码效率上获得极大的好处。
STL 大致可以分为三大类:
算法(algorithm) 、容器 (container) 、迭代器
(iterator)。
STL 容器是一些模板类,提供了多种组织数据的常用方法,例如vector(向量,
类似于数组) 、list( 列表,类似于链表) 、deque(双向队列) 、set(集合) 、
map(映象) 、stack( 栈) 、queue( 队列) 、priority_queue(优先队列) 等,
通过模板的参数我们可以指定容器中的元素类型。
STL 算法是一些模板函数,提供了相当多的有用算法和操作,从简单如
for_each (遍历)到复杂如stable_sort (稳定排序)。
STL 迭代器是对C 中的指针的一般化,用来将算法和容器联系起来。
几乎所有
的STL 算法都是通过迭代器来存取元素序列进行工作的,而STL 中的每一个
容器也都定义了其本身所专有的迭代器,用以存取容器中的元素。
有趣的是,
普通的指针也可以像迭代器一样工作。
熟悉了STL 后,你会发现,很多功能只需要用短短的几行就可以实现了。
通过
STL ,我们可以构造出优雅而且高效的代码,甚至比你自己手工实现的代码效
果还要好。
STL 的另外一个特点是,它是以源码方式免费提供的,程序员不仅可以自由地
使用这些代码,也可以学习其源码,甚至按照自己的需要去修改它。
下面是用STL 写的题Ugly Numbers的代码:
#include
#include
using namespace std;
typedef pair
int main()
{
unsigned long result[1500];
priority_queue < node_type, vector
greater
Q.push( make_pair(1, 2) );
for (int i = 0; i < 1500; i++)
{
node_type node = Q.top();
Q.pop();
switch(node.second)
{
case 2:
Q.push( make_pair(node.first * 2, 2) );
case 3:
Q.push( make_pair(node.first * 3, 3) );
case 5:
Q.push( make_pair(node.first * 5, 5) );
}
result[i] = node.first;
}
int n;
cin >> n;
while (n > 0)
{
cout << result[n-1] << endl;
cin >> n;
}
return 0;
}
在ACM 竞赛中,熟练掌握和运用STL 对快速编写实现代码会有极大的帮助。
二、使用STL
在C++ 标准中,STL 被组织为以下的一组头文件(注意,是没有.h后缀的!
):
algorithm / deque / functional / iterator / list / map
memory / numeric / queue / set / stack / utility / vector
当我们需要使用STL 的某个功能时,需要嵌入相应的头文件。
但要注意的是,
在C++ 标准中,STL 是被定义在std 命名空间中的。
如下例所示:
#include
int main()
{
std:
:
stack
s.push(0);
...
return 0;
}
如果希望在程序中直接引用STL ,也可以在嵌入头文件后,用using
namespace 语句将std 命名空间导入。
如下例所示:
#include
using namespace std;
int main()
{
stack
s.push(0);
...
return 1;
}
STL 是C++ 语言机制运用的一个典范,通过学习STL 可以更深刻地理解C++
语言的思想和方法。
在本系列的文章中不打算对STL 做深入的剖析,而只是想
介绍一些STL 的基本应用。
有兴趣的同学,建议可以在有了一些STL 的使用经验后,认真阅读一下《C++
STL 》这本书(电力出版社有该书的中文版)。
ACM / ICPC 竞赛之STL--pair
STL 的
表示一个二元组或元素对,并提供了按照字典序对元素对进行大小比较的比较
运算符模板函数。
例如,想要定义一个对象表示一个平面坐标点,则可以:
吉林大学ACM Group
39
pair
cin >> p1.first >> p1.second;
pair 模板类需要两个参数:
首元素的数据类型和尾元素的数据类型。
pair 模
板类对象有两个成员:
first和second ,分别表示首元素和尾元素。
在
< 、 > 、 <= 、 >= 、 == 、 !
= ,
其规则是先比较first,first相等时再比较second ,这符合大多数应用的
逻辑。
当然,也可以通过重载这几个运算符来重新指定自己的比较逻辑。
除了直接定义一个pair 对象外,如果需要即时生成一个pair 对象,也可以
调用在
make_pair。
make_pair 需要两
个参数,分别为元素对的首元素和尾元素。
在题1067--Ugly Numbers 中,就可以用pair 来表示推演树上的结点,用
first表示结点的值,用second 表示结点是由父结点乘以哪一个因子得到的。
#include
#include
using namespace std;
typedef pair
int main()
{
unsigned long result[1500];
priority_queue < node_type, vector
greater
Q.push( make_pair(1, 2) );
for (int i = 0; i < 1500; i++)
{
node_type node = Q.top();
Q.pop();
switch(node.second)
{
case 2:
Q.push( make_pair(node.first * 2, 2) );
case 3:
Q.push( make_pair(node.first * 3, 3) );
case 5:
Q.push( make_pair(node.first * 5, 5) );
}
result[i] = node.first;
}
int n;
cin >> n;
while (n > 0)
{
cout << result[n-1] << endl;
cin >> n;
}
return 0;
}
反映了STL 设计的基本思想。
有意深入了解和研究STL 的同学,仔细阅读和
体会这个简单的头文件,不失为一种入门的途径。
ACM / ICPC 竞赛之STL--vector
在STL 的
容器以连续数组的方式存储元素序列,可以将vector 看作是以顺序结构实现
的线性表。
当我们在程序中需要使用动态数组时,vector 将会是理想的选择,
vector 可以在使用过程中动态地增长存储空间。
vector 模板类需要两个模板参数,第一个参数是存储元素的数据类型,第二
个参数是存储分配器的类型,其中第二个参数是可选的,如果不给出第二个参
数,将使用默认的分配器。
下面给出几个常用的定义vector 向量对象的方法示例:
vector
定义一个空的vector 对象,存储的是int 类型的元素。
vector
定义一个含有n 个int 元素的vector 对象。
vector
定义一个vector 对象,并从由迭代器first和last 定义的序列[first,
last)中复制初值。
vector 的基本操作有:
s[i]
直接以下标方式访问容器中的元素。
s.front()
返回首元素。
s.back()
返回尾元素。
s.push_back(x)
向表尾插入元素x 。
s.size()
返回表长。
s.empty()
当表空时,返回真,否则返回假。
s.pop_back()
删除表尾元素。
s.begin()
返回指向首元素的随机存取迭代器。
s.end()
返回指向尾元素的下一个位置的随机存取迭代器。
s.insert(it, x)
向迭代器it指向的元素前插入新元素val 。
s.insert(it, n, x)
向迭代器it指向的元素前插入n 个x 。
s.insert(it, first, last)
将由迭代器first和last 所指定的序列[first, last) 插入到迭代器it
指向的元素前面。
s.erase(it)
删除由迭代器it所指向的元素。
s.erase(first, last)
删除由迭代器first和last 所指定的序列[first, last) 。
s.reserve(n)
预分配缓冲空间,使存储空间至少可容纳n 个元素。
s.resize(n)
改变序列的长度,超出的元素将会被删除,如果序列需要扩展(原空间小于n ),
元素默认值将填满扩展出的空间。
s.resize(n, val)
改变序列的长度,超出的元素将会被删除,如果序列需要扩展(原空间小于n ),
将用val 填满扩展出的空间。
s.clear()
删除容器中的所有的元素。
s.swap(v)
将s 与另一个vector 对象v 进行交换。
s.assign(first, last)
将序列替换成由迭代器first和last 所指定的序列[first, last) 。
[first, last) 不能是原序列中的一部分。
要注意的是,resize 操作和clear操作都是对表的有效元素进行的操作,但
并不一定会改变缓冲空间的大小。
另外,vector 还有其他一些操作如反转、取反等,不再一下列举。
vector 上还定义了序列之间的比较操作运算符(>, <, >=, <=, ==, !
=) ,
可以按照字典序比较两个序列。
还是来看一些示例代码。
输入个数不定的一组整数,再将这组整数按倒序输出,
如下所示:
#include
#include
using namespace std;
int main()
{
vector
int x;
while (cin>>x) L.push_back(x);
for (int i=L.size()-1; i>=0; i--) cout << L[i] << " ";
cout << endl;
return 0;
}
ACM / ICPC 竞赛之STL--iterator 简介
iterator(迭代器) 是用于访问容器中元素的指示器,从这个意义上说,
iterator(迭代器) 相当于数据结构中所说的“ 遍历指针” ,也可以把
iterator(迭代器) 看作是一种泛化的指针。
STL 中关于iterator(迭代器) 的实现是相当复杂的,这里我们暂时不去详细
讨论关于iterator(迭代器) 的实现和使用,而只对iterator(迭代器) 做一
点简单的介绍。
简单地说,STL 中有以下几类iterator(迭代器) :
输入iterator(迭代器) ,在容器的连续区间内向前移动,可以读取容器内任
意值;
输出iterator(迭代器) ,把值写进它所指向的容器中;
前向iterator(迭代器) ,读取队列中的值,并可以向前移动到下一位置
(++p, p++);
双向iterator(迭代器) ,读取队列中的值,并可以向前向后遍历容器;
随机访问iterator(迭代器), 可以直接以下标方式对容器进行访问,
vector 的iterator(迭代器) 就是这种iterator(迭代器) ;
流iterator(迭代器) ,可以直接输出、输入流中的值;
每种STL 容器都有自己的iterator(迭代器) 子类,下面先来看一段简单的示
例代码:
#include
#include
using namespace std;
main()
{
vector
for (int i = 0; i < 10; i++) s.push_back(i);
for (vector
:
iterator it = s.begin(); it !
= s.end();
it++)
cout << *it << " ";
cout << endl;
return 1;
}
vector 的begin()和end()方法都会返回一个vector:
:
iterator 对象,
分别指向vector 的首元素位置和尾元素的下一个位置(我们可以称之为结束
标志位置)。
对一个iterator(迭代器) 对象的使用与一个指针变量的使用极为相似,或者
可以这样说,指针就是一个非常标准的iterator(迭代器) 。
再来看一段稍微特别一点的代码:
#include
#include
吉林大学ACM Group
40
using namespace std;
main()
{
vector
s.push_back
(1);
s.push_back
(2);
s.push_back(3);
copy(s.begin(), s.end(), ostream_iterator
"));
cout << endl;
return 1;
}
这段代码中的copy 就是STL 中定义的一个模板函数,copy(s.begin(),
s.end(), ostream_iterator
s.begin()至s.end()( 不含s.end()) 所指定的序列复制到标准输出流
cout 中,用" " 作为每个元素的间隔。
也就是说,这句话的作用其实就是将表
中的所有内容依次输出。
iterator(迭代器) 是STL 容器和算法之间的“ 胶合剂” ,几乎所有的STL 算
法都是通过容器的iterator(迭代器) 来访问容器内容的。
只有通过有效地运
用iterator(迭代器) ,才能够有效地运用STL 强大的算法功能。
ACM / ICPC 竞赛之STL--string
字符串是程序中经常要表达和处理的数据,我们通常是采用字符数组或字符指
针来表示字符串。
STL 为我们提供了另一种使用起来更为便捷的字符串的表达
方式:
string 。
string 类的定义在头文件
string 类其实可以看作是一个字符的vector ,vector 上的各种操作都可以
适用于string ,另外,string 类对象还支持字符串的拼合、转换等操作。
下面先来看一个简单的例子:
#include
#include
using namespace std;
int main()
{
string s = "Hello!
", name;
cin >> name;
s += name;
s += '!
';
cout << s << endl;
return 0;
}
再以题1064--Parencoding为例,看一段用string 作为容器,实现由P
代码还原括号字符串的示例代码片段:
int m;
cin >> m; // P 编码的长度
string str; // 用来存放还原出来的括号字符串
int leftpa = 0; // 记录已出现的左括号的总数
for (int j = 0; j < m; j++)
{
int p;
cin >> p;
for (int k = 0; k < p - leftpa; k++) str += '(';
str += ')';
leftpa = p;
}
ACM / ICPC 竞赛之STL--stack / queue
stack( 栈) 和queue( 队列) 也是在程序设计中经常会用到的数据容器,STL
为我们提供了方便的stack( 栈) 的queue( 队列) 的实现。
准确地说,STL 中的stack和queue不同于vector 、list 等容器,而是对
这些容器的重新包装。
这里我们不去深入讨论 STL 的stack和queue的实现
细节,而是来了解一些他们的基本使用。
1 、stack
stack模板类的定义在
stack模板类需要两个模板参数,一个是元素类型,一个容器类型,但只有元
素类型是必要的,在不指定容器类型时,默认的容器类型为deque。
定义stack对象的示例代码如下:
stack
stack
stack的基本操作有:
入栈,如例:
s.push(x);
出栈,如例:
s.pop(); 注意,出栈操作只是删除栈顶元素,并不返回该元素。
访问栈顶,如例:
s.top()
判断栈空,如例:
s.empty(),当栈空时,返回true。
访问栈中的元素个数,如例:
s.size()
下面是用string 和stack写的解题1064--Parencoding的程序。
#include
#include
#include
using namespace std;
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
int m;
cin >> m;
string str;
int leftpa = 0;
for (i
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- STL 线段 代码