1、sort()函数
==sort()==函数类似于快速排序,时间复杂度为nlog2n。
头文件:#include<algorithm>
sort(begin, end, cmp) 其中begin是指向待排序的数组的第一个元素指针,end是最后一个元素的下一个位置的指针,cmp参数为排序准则。cmp默认是按照升序排序,也可以改变参数,greater<数据类型>() //从大到小排序 less<数据类型>() //从小到大;也可以自定义排序标准。自定义一个函数,里面写排序标准,然后放到cmp位置上。还可以对结构体进行排序,也是自定义以下排序标准就好了。
2、一维前缀和
构造前缀和数组。
生成前缀和:for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i]; (注意从1开始)
求 l,r 中所有元素的和。
s[l] = a1 + a2 + … + al
s[r] = a1+ a2 + … + ar
s[r]-s[l] = a(l+1) + a(l+2) + … + ar 会发现少了一个 al,所以应该写成 s[r]-s[l-1]
3、二维前缀和
构造前缀和数组。
在写代码的时候,会出现一个奇怪的问题,就是如果把数组a和s定义在main函数里面,会发生错误,且没有提示,暂时不知道是什么原因,就算写成 a[N][N]={0}和s[N][N]={0}也不可以,上网一查估计是因为如果将其定义在main函数里面的话,初始值是由编译器决定的,不一定为0,且对于a[N][N]={0}这样的语句,它的定义是不明确的。
如果把数组设置为全局变量,一定是会被初始化为0的。
编译器:Dev-C++ 5.11
#include<iostream>
using namespace std;
//const int N=1010; //也可以
#define N 1010
int a[N][N];
int s[N][N];
int main()
{
int n,m,q;
// int a[N][N]={0},s[N][N]={0}; //不可以这样子写
cin>>n>>m>>q;
for(int i=1; i<=n; i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
for(int i=1; i<=n;i++){
for(int j=1;j<=m;j++){
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];//生成前缀和**
}
}
while(q--)
{
int x1,x2,y1,y2;
cin>>x1>>y1>>x2>>y2;
cout<<s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1]<<endl;
}
return 0;
}
给出参考数据和答案:
输入:
3 4 3
1 7 2 4
3 6 2 8
2 1 2 3
1 1 2 2
2 1 3 4
1 3 3 4
输出:
17
27
21
4、一维差分
构造差分数组。
原数组为 a1…an,构造数组b使得 bi 的前缀和为 ai 。如 ai = b1 + b2 + b3 +…+ bi ;
b1 = a2 - a1;
b2 = a3 - a2;
b3 = a4 - a3;
b4 = a5 - a4;
对 [ l , r ]这个范围的 ai 都加上 c 的做法:
让 b[l]+c 然后再 b[r+1]-c ;
原因:
5、二维差分
构造差分数组。
6、二分算法
需要注意的是,数值本身是有序的;返回的是指针。可以用 lower_bound(a, a+5, 5) - a; 的方法找到下标值。容器也是一样的,vector、set。
在小到大的排序中:
1、 lower_bound(起始地址,结束地址,要查找的数值key) 函数:返回第一个大于等于key值的位置。
2、upper_bound(起始地址,结束地址,要查找的数值key) 函数:返回第一个大于key值的位置。
在大到小的排序中:
3、lower_bound(begin, end, key, greater() )函数:找第一个小于等于key值的位置。
4、upper_bound(begin, end, key, greater() ) 函数:找第一个小于key值的位置。
上述四个函数,如果找不到的话,就返回 end末位置。
注意:一定要按照排序顺序来使用这四个函数,如果是在非递减的数组中,不能使用3和4的函数,会找不到的。
binary_search(起始地址,结束地址,要查找的数值key)函数:查找key是否存在。返回布尔类型。true/false。
7、队列
例题acw:132.小组队列
可以用数组模拟队列。
int q[10000] , f = 0 , r = 1 ; //数组模拟队列,f为队头,r为队尾的下一个位置。
使用stl封装好的队列:
头文件: <queue>
queue<int> q; //定义int队列
q.push(); //入队
q.pop(); //出队
q.front(); //返回队头元素
q.back(); //返回队尾元素
q.size(); //返回队列的大小
q.empty(); //判断队列是否为空,是返回1,不是返回0
注意:pop、push函数是void类型的,empty函数是bool类型的,front、back返回的都是指针类型的。
优先队列、单调队列、双端队列。
8、map
例题:P1918.保龄球
map容器是一个键值对key-value的映射。
头文件:#include <map>
#include<map>
//初始化格式:map<key_type, value_type> mp;
map<int, bool> mp;
mp.size(); //元素个数
mp.empty(); //判断是否为空
mp.clear(); //清空map容器
mp.begin(); //首选代器
mp.end(); //尾选代器