刻师傅教我做牛杂 | 杂碎知识点整理
刻师傅:剑光如我,斩尽芜杂
雷史莱姆:免疫免疫免疫免疫
我:师傅,这免疫也要学吗?
刻师傅:......
刻师傅:学会了吗?
我:学会了~
刻师傅:你来
我:免疫免疫免疫免疫免疫
刻师傅:没教你学这个啊喂!
我:啊我错了刻师傅,我再来一遍
刻师傅:......
我:剑光如我,斩尽牛杂
刻师傅:不是让你来学剑法的吗?
我:我不是来学做牛杂的吗?
STL
nth_element
nth_element(x,x+k,x+n)
其中:
x是数组名k是要求的第k小的元素
n是元素个数
主要用来将数组元素中第k小的整数排出来并在数组中就位
实例:Note6-2 第一题
lower_bound和upper_bound
(这里的方法是求下标)
int p=lower_bound(l+1,l+1+n,k)
int p=wpper_bound(l+1,l+1+n,k)
其中:
l是一个数组名n是它的长度
l+1是起始端
l+1+n是终止端
这里的区间是前闭后开区间
k是要查找的数
lower_bound用来查大于等于k的最小的数
upper_bound用来查大于k的最小的数
如果数组内的数全都小于k的话,会返回last(数组下标是越界的)
实例:洛谷P2782
next_permutation
这是一个名字贼长的函数
库
include <algorithm> 或 include <bits/stdc++.h>
主要用法:
next_permutation(f+1,f+1+len);
或者
next_permutation(str.begin(),str.end());
总之就是输出一个起始位和结束位
用途是求出在全排列中,当前排列的下一个排列,这里的下一个的定义是字典序的下一个
比如说我们有一个字符串abc
那它的排列一共有6种,分别是:abc,acb,bac,bca,cab,cba
这里的排列就是按照字典序排列的,abc的下一个就是acb
实例:洛谷P1088
stack
顾名思义,这个就是STL栈
库
include <stack> 或 include <bits/stdc++.h>
声明一个stack
是一个STL容器比较常用的方法
stack<数据类型> 栈的名称;
为了方便,下文的栈名称默认为s
主要函数
s.empty();
判断栈s是否为空,若为空返回true,若不为空返回false,这个函数常在 while/if 时使用s.push(x);
将x压入栈,这里的x和栈的类型要求保持一致s.size();
返回栈中有几个元素s.pop();
将栈首出栈,无返回值s.top();
将栈首的值返回,但不进行操作,常常和pop()一起使用
queue
顾名思义,这是一个STL库中的队列容器
库
include <queue> 或 include <bits/stdc++.h>
声明一个queue
一种STL容器比较常用的方法
queue<数据类型> 名称;
为了方便,下文的队列名称默认为q
主要函数
q.empty();
判断q是否为空,若为空返回true,若不为空返回false,这个函数常在 while/if 时使用q.push(x);
将x入队,这里的x和队列的类型要求保持一致q.size();
返回队列中有几个元素q.pop();
将队首出栈,无返回值q.front();
将队首的值返回,但不进行操作,常常和pop()一起使用q.back();
将队尾的值返回,其他同front
priority_queue
顾名思义,这是一个STL库中的优先队列容器
库
include <queue> 或 include <bits/stdc++.h>
声明一个priority_queue
一种STL容器比较常用的方法,但是略有不同
priority_queue<int> pq;
上面这个默认的是越大的整数优先级越高的优先队列(也就是大根堆)
如果需要其他的,可以自己重载 逻辑运算符
然后声明的时候就是这样
priority_queue<int,vector<int>,cmp> pq;
struct cmp{
bool operator () (int a,int b)
{
blablablablabla.......;
}
};
当然STL也为我们提供了一些基础的重载
如priority_queue<int,vector<int>,greater<int> > pq;
这就是一个小根堆
为了方便,下文的队列名称默认为pq
主要函数
pq.empty();
判断pq是否为空,若为空返回true,若不为空返回false,这个函数常在 while/if 时使用pq.push(x);
将x入队,这里的x和优先队列的类型要求保持一致pq.size();
返回队列中有几个元素pq.pop();
将队首出栈,无返回值pq.top();
将队首的值返回,但不进行操作,常常和pop()一起使用,要注意的是,这里的取首方法和queue不同,因为在这里第一个入队元素不一定是第一个出队的元素,所以不能用frontpq.back();
将队尾的值返回,其他同top
set
顾名思义,这是一个集合,这里的集合就是数学上的集合,具有无序性,确定性,互异性,具体性质内容的推荐BDFS
库
include <set> 或 include <bits/stdc++.h>
声明一个set
一种STL容器比较常用的方法
set<数据类型> 名称;
为了方便,下文的集合名称默认为s
主要函数
s.empty();
判断s是否为空,若为空返回true,若不为空返回false,这个函数常在 while/if 时使用s.insert(x);
将x加入集合,要注意的是,为了满足集合的互异性,x只会在集合中出现一次s.size();
返回集合中有几个元素s.clear();
清空集合ss.begin();
返回s中的第一个元素,这里是返回一个指针s.end();
返回s中的最后一个元素,其余同begin
vector
向量,简单来说就是不定长数组,它会随着里面元素的增长开空间
库
include <vector> 或 include <bits/stdc++.h>
声明一个vector
一种STL容器比较常用的方法
vector<数据类型> 名称;
为了方便,下文的名称默认为v
主要函数
v.empty();
判断v是否为空,若为空返回true,若不为空返回false,这个函数常在 while/if 时使用v.push_back(x);
将x从v的尾部插入,这里的x和vector的类型要求保持一致v.size();
返回vector中有几个元素v.pop_back();
把v的尾端元素删除,无返回值v.resize(x);
保留1~x的元素
pair
类似数对,实际上就是一个二元组
库
include <pair> 或 include <bits/stdc++.h>
声明一个pair
pair<数据类型,数据类型> 名称;
为了方便,下文的pair名称默认为p
主要用法
make_pair(x,y);
将x和y的值合为一个新的二元组pair<int,int> p(x,y);
将x和y的值合为一个新的二元组int f=p.first,s=p.second;
将p这个二元组中的第一个元素的值赋值给f,第二个值赋值给s- 二元组可以直接使用 < 和 > 进行比较,默认使用first,即第一个元素进行比较
- 二元组可以使用 == 进行比较是否一样,判断条件是first和second依次相同
- 二元组可以套娃:
pair<pair<pair<int,int>,pair<int,int> >,pair<int,int> > TWP;
,取值方式也一样套娃即可,如:TWP.first.first.second
定理
Dilworth定理
狄尔沃斯定理(Dilworth's theorem)亦称偏序集分解定理,是关于偏序集的极大极小的定理,该定理断言:对于任意有限偏序集,其最大反链中元素的数目必等于最小链划分中链的数目。此定理的对偶形式亦真,它断言:对于任意有限偏序集,其最长链中元素的数目必等于其最小反链划分中反链的数目,由偏序集P按如下方式产生的图G称为偏序集的可比图:G的节点集由P的元素组成,而e为G中的边,仅当e的两端点在P中是可比较的,有限全序集的可比图为完全图
上面那个我看不懂
下面是我的理解
把一个数列划分成最少的 最长下降子序列 的数目就等于这个数列的最长上升子序列 的长度
举个例子:
如数列 1 2 2 3 2 3
最长下降子序列可以分成:1,2,2,3 2,3 ——5个
最长上升的子序列就是:1 2 2 3 3 ——长度为5
我看了很多的解释,感觉都看不懂,于是在这些解释的基础上自己导出得出这样一个解释
如果我这个解释不准确请及时向我提出来!
我不想让自己一直错误解释一个定理,再或者误导别人
参考到的解释:
实例:Note8 第三题