
算法与数据结构
文章平均质量分 63
学习算法与数据结构特此记录
气派飞鹰
个人主页 qipaifeiying.github.io
展开
-
【C++ STL 容器】——概述
容器分类序列性容器:vector,deque,list关联性容器:set,multiset,map,multimap容器适配器:stack,queue容器共性容器一般来说都有如下函数默认构造函数复制构造函数析构函数empty:判断容器是否为空max_size:返回容器中最大元素个数size:返回容器中当前元素个数operator=:将一个容器赋给另一个容器operator<:比较容器operator=:operator>:operator>=;ope原创 2021-06-11 19:35:03 · 150 阅读 · 0 评论 -
【C++ STL 容器】——deque
简介deque容器为一个给定类型的元素进行线性处理,像向量一样,他能够快速地随机访问任一个元素,并且能够高效地插入和删除容器的尾部元素。但它由于vector不同,deque支持高效插入和删除容器的头部元素,因此也叫做双端队列。常用函数构造函数:deque():创建一个空dequedeque(int size):创建一个deque,元素个数为sizedeque(int size,const T& t);创建一个deque,元素个数为size,且值均为t。deque(const deq原创 2021-06-11 20:23:46 · 218 阅读 · 0 评论 -
【C++ STL 容器】——集合
介绍set,multiset都是集合类,差别在于set中不允许有重复元素,multiset中允许有重复元素。常用函数构造函数set(const Pred& comp=Pred(),const A& al=A()):创建空集合。set(const set& x):复制构造函数。set(const value_type * first,const value_type * last,const Pred& comp=Pred()):复制[first,last)之间原创 2021-07-16 09:35:31 · 204 阅读 · 0 评论 -
【C++ STL】——字符串
字符串创建和初始化基本方法迭代器创建方法字符串操作插入创建和初始化头文件<string>基本方法string s1;string s2("Hello");string s3(s2);string s4(s2,0,3); string s5 = "Hi"; string s6 = s2+"Hi";s4 第一个参数是string类型,第二个和第三个分别表示偏移量和计数量,即从第0个字符开始连续读3个字符s5单一赋值,可直接把char型数组赋值给s5类似s6这样可以,但原创 2021-05-31 21:48:44 · 583 阅读 · 2 评论 -
【C++ STL 容器】——队列和堆栈
简介队列和堆栈都是比较常用的数据结构。队列只允许在表的一端插入,在另一端删除,允许插入的一端叫做队尾,允许删除的一端叫做队头,是先进先出的线性表。栈允许在表的一端进行插入和删除操作,是一种后进先出的线性表。常用函数构造函数queue(class T,class Container=deque<T>);创建元素类型为T的空队列,默认容器是deque。stack(class T,class Container=deque<T>);创建元素类型为T的空堆栈,默认容器是dequ原创 2021-06-14 11:02:08 · 228 阅读 · 0 评论 -
【C++ STL 容器】——bitset
概念bitset可以看做是二进制位的容器,并提供了位的相关操作函数。常用函数构造赋值函数bitset();bitset(const bitset&):复制构造函数bitset(unsigned long val):由无符号长整型数构建位容器bitset(const string& str,size_t pos=0,size_t n = -1):由字符串创建位容器bitset& operator=(const bitset&):赋值操作逻辑运算操作(与原创 2021-07-16 09:10:23 · 476 阅读 · 0 评论 -
【C++ STL 容器】——list
简介list是一个双向链表,他有一个重要性质:插入操作和删除操作都不会造成原有的list迭代器失效,每次插入或删除一个元素都会配置或释放一个元素空间。常用函数构造函数list<Elem>c;创建一个空的listlist<Elem>c1(c2);复制另一个同类型元素的listlist<Elem>c(n);创建n个元素的list,每个元素值由默认构造函数确定list<Elem>c(n,elem);创建n个元素的list,每个元素值为elemli原创 2021-06-14 10:44:48 · 175 阅读 · 0 评论 -
【C++ STL 容器】——vector
概述vector容器也被称作向量,实现了动态的数组,用于元素数量变化的对象数组,算是比较常用的容器。常用函数构造函数vector();创建一个空vectorvector(int size); 创建一个vector,元素个数为sizevector(int size,const T& x);创建一个vector,元素个数为size,且值均为xvector(const vector&);复制构造函数增加函数void push_back(const T& t);向原创 2021-06-11 19:57:37 · 869 阅读 · 0 评论 -
【C++ STL 容器】——映射
介绍常用的映射类是map,multimap。在前述的各个容器中,仅保存着一样东西,但是在映射中将会得到两样东西:关键字以及作为对关键字进行查询得到的结果值,即一对值<Key,Value>。map单映射中,Key与Value是一对一的关系;multimap多映射中,Key与Value可以是一对多的关系。常用函数构造函数map(const Pred& comp=Pred(),const A& al=A()):创建空映射。map(const map& x):复制构原创 2021-07-16 10:13:40 · 440 阅读 · 0 评论 -
【C++ STL 容器】——优先队列
概念优先队列即priority_queue类,带优先权的队列,优先权高度元素优先出队。与普通队列相比,共同点都是对队头做删除操作,队尾做插入操作,但不一定遵循先进先出原则,priority_queue是一个基于某个几本序列进行构建的适配器,默认的序列容器是vector。常用函数构造函数priority_queue(const Pred& pr = Pred(),const allocator_type& al = allocator_type());创建元素类型为T的空优先队列,原创 2021-06-14 11:19:53 · 325 阅读 · 0 评论 -
【模板】——快排
快排void qSort(int a[], int l, int r){ if (l < r) { int i = l, j = r, temp = a[l]; while (i < j) { while (i < j && a[j] >= temp) j--; if (i < j) a[i++] = a[j]; while (i <原创 2021-05-28 17:42:48 · 94 阅读 · 0 评论 -
【OJ模板】——求指定非连续子序列个数
例如nunhehhehahaahahahahahahaahaahahahahha中nunhehheh的个数思路:dp[i][j]表示原字符串的前i个字符中含有子序列前j个字符组成的序列的个数,然后我们用滚动数组减少空间。#include <bits/stdc++.h>#define ll long longll dp[10];char str[100]="nunhehhehahaahahahahahahaahaahahahahha";char sstr[100] = "nunhehh原创 2021-10-11 11:41:30 · 262 阅读 · 0 评论 -
【OJ模板和问题记录】——求最长子序列
问题描述:求给定序列的最长上升子序列,子序列不一定是连续的。题目地址POJ2533 Longest Ordered Subsequence思路:动态规划,用dp[i]表示以第i个数字结尾的最长子序列,dp[i]等于比他小的数字dp[j]+1,遍历后找到最大值即可。O(n2)代码:#include <iostream>#define maxn 1001using namespace std;int a[maxn];int dp[maxn];int main(){ cin原创 2021-07-31 10:04:55 · 191 阅读 · 0 评论 -
【语法问题】——堆的运算符重载
阿凡达原创 2021-07-20 09:23:39 · 285 阅读 · 0 评论 -
【模板】——c与c++字符串常用方法
C1.gets()函数,读取一行char * str;while(gets(str)!=NULL){}2.scanf()while(scanf("%s",str)!=EOF)){};C++1.getline()string str;while(!cin.eof()){getline(cin,str);}2. cinstring str;while(!cin.eof()){cin >> str;}原创 2022-02-24 16:51:31 · 583 阅读 · 0 评论 -
【错题记录】——常见错误(长期更新)
文章目录codeForces 字符串记录一些自己做题过程中由于考虑不全面出现的各种奇怪的问题codeForces 字符串题目地址CodeForces B Reverse string题意:给一个字符串s,从s的一个位置开始向右走任意(可以是0)个字符,每到达一个位置,就将当前位置的字符记录下来,初始位置字符也要记录,然后向左走任意个字符,记录字符,问是否能生成t字符串,能输出yes,否则输出no思路:先判断t是不是本身就是s的子串,t的逆序是不是s的子串,然后找到t的一个位置左右两端的字符都相同,原创 2021-09-26 22:40:16 · 376 阅读 · 0 评论 -
【模板】——直线与直线的交点
pair<double,double> jd (double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4) { if (x1==x2&&y1==y2) return make_pair(1e18,1e18); //(x1,y1),(x2,y2)组成的直线和(x3,y3),(x4,y4)组成的直线的交点 double k1=(x1==x2?1e18:.原创 2021-11-18 17:09:19 · 217 阅读 · 0 评论 -
【OJ模板】——KMP算法
参考博客https://zhuanlan.zhihu.com/p/83334559next数组的预处理void pre(){ p[1]=0; j=0; for(int i = 1;i <= len;i++) { while(j>0&&s[i+1]!=s[j+1]){ j=p[j]; } if(s[j+1]==s[i+1]) j++; p[i+1]=j; }}search函数int search(){int j=0;for(i原创 2022-03-19 17:01:43 · 559 阅读 · 0 评论 -
【问题记录】——求序列子区间最大平均值
问题描述给定一个序列求其长度大于f的子区间的平均值的最大值思路求平均值可以用二分法来找平均值,先假设一个平均值,让原序列a减去假设平均值生成一个新序列b,b序列中有正有负,将b序列的前缀和存在sum数组中,区间[i,j]的和表示为sum[j]-sum[i],如果存在区间和大于0,说明平均值还可以更大一些。这样求得的平均值稍有误差,可以控制误差的数量级。实现代码int a[maxn]; //a数组double b[maxn]; //a数组减去假设平均值double sum[m原创 2021-07-28 15:45:37 · 1583 阅读 · 0 评论 -
【模板】——求序列逆序对数
ll MergeSort(int s[], int left, int middle, int right){ int i = left, j = middle; int b[right - left + 1]; int index = 0; ll sum = 0; int t = 0; while (i < middle && j <= right) { if (s[i] > s[j]) { b[index++] = s[j++]; t原创 2021-07-28 15:35:09 · 212 阅读 · 0 评论 -
【问题记录】——高精度小数
高精度问题相关题目【题目记录】——ICPC大连2016这个题目的数据大小达到了1010010^{100}10100,小数部分也应该达到10−10010^{-100}10−100,JAVA对于精度的限制,有这样的技巧。在下面的代码中,试图将5\sqrt{5}5的结果的精度逼近10−10010^{-100}10−100import java.math.BigDecimal;import java.math.BigInteger;import java.util.Scanner;public c原创 2022-03-06 11:04:29 · 260 阅读 · 0 评论 -
【问题记录】——memset效率
今天刷oj的时候发现用memset导致内存超限的问题,但是手动循环却不会超限。很好奇,在网上搜了一下,没有什么明确的答案,但是确实有人遇到过由于memset导致的时间超限,内存超限的问题。但是有的说memset比手动循环速度快,总之,如果不需要把整个数组初始化,就不要用memset了,而是手动for循环。...原创 2021-08-01 13:22:08 · 432 阅读 · 0 评论 -
【OJ注意点 超时】——cout和scanf
输入输出尽量用printf和scanf,cout和cin虽然方便,但是速度稍慢一点,有时候的题目会被这一点卡时间。原创 2021-07-16 15:39:10 · 253 阅读 · 0 评论 -
【OJ模板】——BFS分层遍历技巧
BFS分层遍历有时候BFS分层遍历需要考虑到当前遍历的节点是第几层,在这里有一个技巧。//遍历链式前向星存储树void BFS(int s) { queue<int>q; q.push(s); vis[s]=1; while(!q.empty()) { int len=q.size(); while(len--) { int u=q.top(); q.pop();原创 2022-03-23 16:20:55 · 990 阅读 · 0 评论 -
【模板】——找出一个数的质因数
在网上找了好多方法,并没有什么特别的方法,就是遍历。//先来一遍ola筛,筛出所有素数const int N=3e7+1;bool IsPrime[N];//真值为素数int Prime[N],cnt;//存储的素数从下标1开始vector<int>v;void ola(int n) { //筛选到n memset(IsPrime,1,sizeof(IsPrime));//初始化 //假设每个数都为素数 IsPrime[1]=IsPrime[0]=0; for(int i=2原创 2022-03-16 16:31:55 · 823 阅读 · 0 评论 -
【算法与数据结构】——AC自动机
参考文章AC自动机原创 2022-03-21 20:19:55 · 1859 阅读 · 0 评论 -
【算法与数据结构】——对抗搜索
参考博客对抗搜索(Adversarial Games)——Min-max搜索 & Aleph-beta剪枝搜索原创 2022-03-12 10:27:08 · 5201 阅读 · 0 评论 -
【算法与数据结构】——字符串哈希
参考二分+哈希参考字符串哈希原创 2022-03-16 16:54:08 · 543 阅读 · 0 评论 -
【算法与数据结构】——后缀自动机
参考博客史上最通俗的后缀自动机详解原创 2022-03-15 10:35:34 · 1429 阅读 · 2 评论 -
【算法与数据结构】——元胞自动机
元胞自动机的概念(CA)不同于一般的动力学模型,元胞自动机不是由严格定义的物理方程或函数确定,而是用一系列模型构造的规则构成。凡是满足这些规则的模型都可以算作是元胞自动机模型。因此,元胞自动机是一类模型的总称,或者说是一个方法框架。其特点是时间、空间、状态都离散,每个变量只取有限多个状态,且其状态改变的规则在时间和空间上都是局部的。通俗解释概念看起来很不直观是吧,元胞自动机是一种用来仿真局部规则和局部联系的方法。典型的元胞自动机是定义在网格上的,每一个点上的网格代表一个元胞与一种有限的状态。变化规则适原创 2022-03-12 09:55:52 · 491 阅读 · 0 评论 -
【算法与数据结构】——后缀数组
参考文章后缀数组原创 2022-03-07 18:12:59 · 797 阅读 · 0 评论 -
【算法与数据结构】——基数排序
文章目录基数排序简介基本原理LSD基本步骤MSD基本步骤基数排序简介基数排序是一种非比较型的排序算法,可以对整数或者字符串进行排序。桶排序的一个好处是算法稳定。基本原理原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。基数排序的方式可以采用LSD(Least significant digital)或MSD(Most significant digital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。MSD:先从高位开始进行排序,在每个关键字上采用桶排序原创 2022-03-04 10:31:38 · 815 阅读 · 0 评论 -
【算法与数据结构】——字典树(Trie)
字典树的创建原创 2022-02-24 16:13:15 · 332 阅读 · 0 评论 -
【算法与数据结构】——约瑟夫环
主要参考约瑟夫环——公式法(递推公式)约瑟夫问题约瑟夫问题是个著名的问题:N个人围成一圈,第一个人从1开始报数,报M的将被杀掉,下一个人接着从1开始报。如此反复,最后剩下一个,求最后的胜利者。解决方案普通解法对于这个问题我们一般想到的解决方法就是用一个数组或者链表来模拟,每次向后遍历,到第M个数的时候就删掉当前的数,如此反复多次即可,复杂度是O(nm),这样的复杂度在数据量比较小的情况下还是可以解决的,但是一旦n和m的值很大就无法在短时间内计算出结果了。公式法约瑟夫环是一个经典的数学问题,我们原创 2021-10-31 21:17:27 · 953 阅读 · 0 评论 -
【算法与数据结构】——单调队列
单调队列分为两种,一种是单调递增的,另外一种是单调递减的。单调队列和单调栈的维护有点像,但是单调队列可以维护一定长度的区间的最大值最小值。百度百科的解释:不断地向缓存数组里读入元素,也不时地去掉最老的元素,不定期的询问当前缓存数组里的最小的元素。用单调队列来解决问题,一般都是需要得到当前的某个范围内的最小值或最大值。举个例子:有 7 6 8 12 9 10 3 七个数字,现在让你找出范围( i-4,i ) 的最小值。那我们就可以这样模拟一遍。先初始化{ 0 } (表示i=0时的值)i=1 -原创 2021-08-06 17:21:41 · 165 阅读 · 0 评论 -
【算法与数据结构】——树的重心
文章目录概念性质找重心例题概念关于下面介绍的性质的证明,主要参考博客算法学习笔记(72): 树的重心计算以无根树每个点为根节点时的最大子树大小,这个值最小的点称为无根树的重心。性质用sizeu(v)size_u(v)sizeu(v)表示以u为根节点时包含v的子树的大小。如果u和v相邻,那么sizeu(v)+sizev(u)=nsize_u(v)+size_v(u)=nsizeu(v)+sizev(u)=n。某个点是树的重心等价于它最大子树大小不大于整棵树大小的一半。树至多有两个重心。原创 2021-09-30 17:51:38 · 610 阅读 · 0 评论 -
【算法与数据结构】——状态压缩DP
状态压缩DP简介在动态规划状态设计中,若状态是一个集合,例如S={1,0,1,1,0},则表示第1,2,4个节点被选中(从右向左对应0-4号节点)。若集合的大小不超过N,则集合中的每个元素都是小于K的正整数,可以把这个集合看作一个N位K进制数,以一个[0,KNK^NKN-1]的十进制整数作为DP状态。可以将S={1,0,1,1,0}看作一个5位二进制数10110,其对应的十进制数为21。这种将集合作为整数记录状态的一类算法叫做状态压缩DP。经典旅行商问题旅行商问题(TSP)指一个旅行商从一个城市出发原创 2021-09-22 17:15:27 · 362 阅读 · 0 评论 -
【算法与数据结构】——树形DP二次扫描与换根
二次扫描与换根在一棵无根树上需要以多个节点为根求解答案,可以运用二次扫描与换根法。具体操作是通过实现一次自底向上的深度优先搜索和一次自顶向下的深度优先搜索来计算“换根”后的解;(1)第1次扫描:任选一个结点为根出发,执行一次深度优先搜索,在递归回溯时自底向上进行状态转移,用子节点的状态更新父节点的状态(2)第2次扫描:从刚才选出的跟出发,再进行一次深度优先搜索,在每次递归前都自顶向下进行状态转移,用父节点的状态更新子节点的状态,计算出“换根”后的结果。...原创 2021-09-05 20:06:40 · 394 阅读 · 0 评论 -
【算法与数据结构】——前缀和,差分
参考博客二维差分差分——(2)二维差分前缀和给定一个数组a,如果有一个数组p,p[i] = p[i-1]+a[i],这个数组p就是a的前缀和数组,p[b]就表示数组a的前b项和。p[b]-p[a-1]就表示数组a的[a,b]区间的和。一维差分给一个数组a,有一个数组p,p[i] = a[i]-a[i-1],这个数组p就是a的差分数组。我们可以看出前缀和数组的差分数组就是原数组差分数组单独使用也是有意义的,比如将原数组看做是一个前缀和数组,它可以维护多次对序列的一个区间加上一个数,并在最后询问某原创 2021-09-11 20:16:46 · 303 阅读 · 0 评论 -
【算法与数据结构】——数位DP(1)
概念数位DP是与数位相关的一类计数类DP,一般用于统计[l,r]区间满足特定条件的元素个数。数位指个位,十位,百位等,数位DP就是在数位上进行动态规划。数位DP在实质上是一种有策略的穷举方式,在子问题求解完毕后将其结果记忆化就可以了。...原创 2021-09-12 15:38:24 · 121 阅读 · 0 评论