
经典算法
文章平均质量分 96
记录常用算法模板
baby的我
社畜先生
展开
-
带括号的四则运算表达式计算
#include<bits/stdc++.h>using namespace std;int fun(int x, char p, int y){ if(p == '+') return x + y ; else if(p == '-') return x - y ; else if(p == '*') return x * y ; else return x / y ; }//计算.原创 2020-05-27 10:39:38 · 643 阅读 · 0 评论 -
spfa(求单源最短路)
一、简介spfa :Shortest Path Faster Algorithm单源最短路:给定一个带权值的有向图,给定图中的一个定点V,则V称为源,V能到达所有的顶点的最短距离称为单源最短路二、图的存储方式#include<bits/stdc++.h>#define inf 0x3f3f3f3f #define M 500005using namesp...原创 2019-05-02 16:26:03 · 403 阅读 · 0 评论 -
求最长递增(递减)子序列
最长子序列指的是在一串数字中,求得一个最大的区间,使得这个区间的所有数都是有规律的一般分为两种,连续与不连续一、连续版直接从前往后遍历,线性遍历,时间复杂度为O(n)#include<bits/stdc++.h>#define M 100005using namespace std;int a[M]={389, 207 ,155 ,300 ,299,170...原创 2019-04-18 19:35:52 · 3002 阅读 · 0 评论 -
拓扑排序
一、简介 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为...原创 2019-05-03 13:46:47 · 405 阅读 · 0 评论 -
KMP匹配算法
一、简介KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。二、算法步骤计算next[ ] 数组的值,其中next[i]= n 表示 以s[i-1] 字符结尾的串 和与 以s[0] 开头的字符串 两个串中最长相等的长度为n...原创 2019-05-03 15:28:56 · 173 阅读 · 0 评论 -
扩展欧几里得算法
一、简介 扩展欧几里得算法是欧几里得算法(又叫辗转相除法)的扩展。除了计算a、b两个整数的最大公约数,此算法还能找到整数x、y(其中一个很可能是负数)。通常谈到最大公因子时, 我们都会提到一个非常基本的事实:给予二整数 a 与 b, 必存在有整数 x 与 y 使得ax + by = gcd(a,b)。有两个数a,b,对它们进行辗转相除法,可得它们的最大公约数——这是众所周知的。然...原创 2019-05-03 18:09:06 · 7325 阅读 · 1 评论 -
逆元运算(除法取模)
一、简介逆元:ax≡1(mod p)当a和p互质时,方程的解 x 称为a关于p的逆元,在普通的四则运算中,只有加减乘三种运算可以根进行分别取余运算,因为这三种运算都是从低位到高位的运算,而对于除法是从高位到低位的运算,显然不能直接进行取余,这时候,就要用到逆元有关的运算。逆元可以近似的看作倒数的概念二、应用例如,如果要求(x / y)%p ,显然不可以(x%p)/(y...原创 2019-05-04 15:59:12 · 8275 阅读 · 1 评论 -
容斥原理
一、简介 在计数时,必须注意没有重复,没有遗漏。为了使重叠部分不被重复计算,人们研究出一种新的计数方法,这种方法的基本思想是:先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复,这种计数的方法称为容斥原理。比如两个集合A,B,我们要求A∩B,A∪B ==A+B-A∩B。如三个集合,A∪B∪C...原创 2019-05-08 13:10:24 · 575 阅读 · 0 评论 -
字典树
字典树一般用来查询一个字符串a,问有多少个字符串以a为前缀用二维数组存储,每个节点都编号,num数组记录以节点结尾的前缀有多少个例如分别插入bananabandbee#include<bits/stdc++.h>using namespace std;int tree[1000005][26];int num[1000005], pos=1...原创 2019-05-06 15:40:08 · 377 阅读 · 0 评论 -
等比数列求和取余
一、二分+快速幂#include<bits/stdc++.h>#define lom long long using namespace std;lom quick(lom a,lom b,lom c)//quick mod{ lom ans=1; a%=c; while(b) { if(b&1) ans=ans*a%c; a=a*a%c;...原创 2019-05-25 22:30:33 · 1873 阅读 · 0 评论 -
C++实现大数类
可以用int、char、string、Bint类型初始化支持各种运算符#include<bits/stdc++.h>#define MAXN 9999#define M 1000#define DLEN 4using namespace std;class Bint{ private: int a[M]; int len; public: Bi...原创 2019-05-26 20:15:51 · 1986 阅读 · 1 评论 -
Andrew算法——凸包问题
Andnew算法是Graham扫描法的变种步骤:把所有点优先按照横坐标x从小到大排序,如果x坐标相等,则按照y坐标从小到大排序 去除重复的点,(unique函数好评) 从左到右扫描下凸包,把满足条件的点放入b数组中 从右到左扫描上凸包,继续把满足条件的点放入b数组中 累加距离遍历点集的时候,利用叉积判断下一个点是在当前方向的左边还是右边,如果是右边满足凸包,删除上一个点,讲这个点...原创 2019-08-06 17:28:50 · 975 阅读 · 0 评论 -
图的遍历
前言 图的遍历比树的遍历就复杂多了,因为它的任意一顶点都可以与其它顶点相连接,因此极有可能存在重复走过某个顶点或漏了某个顶点的遍历过程。而为了避免以上的情况,那就要科学的设计遍历的方案,通常有两种遍历的次序方案,即我们所要讲的深度优先遍历和广度优先遍历。 深度优先遍历 也称深度优化搜索,简称DFS,它的具体思维是从任意一个顶点出发,都可以访问到其他的顶...原创 2018-12-26 14:19:54 · 180 阅读 · 0 评论 -
图的存储结构
前言 图的存储结构相比线性表与树来说就复杂很多,对于线性表来说,是一对一的关系,所以用数组和链表均可以存放。树的结构是一对多的关系,所以我们将数组和链表的特性结合在一起才能更好的存放。而我们的图,是多对多的情况,另外图上的任何一个顶点都可以被看作为第一个顶点,任意点的邻接点也不存在次序关系。下图中各个图是同一个图,只是改变了一下位置而已,从性质上依然是同一个图。 图...原创 2018-12-25 22:27:11 · 1579 阅读 · 0 评论 -
图的概念
前言: 在前面学的线性表的概念中,每个元素只有一个直接前驱和一个直接后继。在树性结构中,数据元素之间是层次关系,并且每一层上的元素都和下一层的多个元素相关,但只能和上一层的一个元素相关。 ——————————这些只是一对一或一对多的关系,而如果要研究多对多的关...原创 2018-12-24 00:17:15 · 2195 阅读 · 0 评论 -
Dijkstra算法——单源最短路
Dijkstra是非常高效又稳定的算法类似于从起点向周围广搜存储:将i节点所有的边用 动态数组e[i] 存储, bool done [i] 记录第i个节点是否已经找到最短路径 在集合中找到最近的点,用堆实现步骤:遍历所有i 所有的边,取最短路 把i 能到达的顶点放入堆中 更新dis 数组b站上这个动图讲的很好:https://www.bilibili.com...原创 2019-08-14 17:16:41 · 306 阅读 · 0 评论 -
树状数组(求逆序对)
一、树状数组是什么树状数组,又称二进制索引树,英文名Binary Indexed Tree之前遇到一个求逆序对的题,看了很多题解都只说了这个树状数组,关于怎么实现的全都避而不谈,我研究了一下午,总算搞出个头绪了一般用来求前缀和,可以把时间复杂度从O(n)降到O(log10 n)非常恐怖,举个例子,假如我们要求从1~1000的前缀和,普通方法需要遍历1000次,而树状数组只需要遍历5次,...原创 2019-04-01 19:17:14 · 20726 阅读 · 42 评论 -
斐波拉契数列的N中求法
No.1 递归版lom recur(lom x){ if(n<=1) return x; else return recur(x-1)+recur(x-2);}简洁明了,一气呵成,将递归的精髓用的淋漓尽致,但是你求一个第一万个数试试,保证很好玩,嗯,递归栈也是有限的,默认栈空间大小只有8M。一般来说,8M的栈空间对于一般程序完全足够。如果8M的栈空间不够使用,那么就需要重新...原创 2019-03-26 18:39:28 · 327 阅读 · 0 评论 -
几种排序算法比较
前言 排序是按照关键字的非递减或非递增顺序对一组记录重新进行排列的操作,是对无规律的一组序列转化为递增或递减的操作。排序的稳定性: 当排序记录中的关键字都部相同时,则任何一个记录的无序序列经过排序后得到的结果都唯一,反之,若存在两个或多个关键字相同时,则得到的结果可能不唯一。 假设Ki=Kj且排序前Ki在Kj之前,排序后Ki仍然在kj之前,则称排序时稳定...原创 2018-12-27 11:52:50 · 8827 阅读 · 4 评论 -
线段树
题目描述如题,已知一个数列,你需要进行下面两种操作:1.将某区间每一个数加上x2.求出某区间每一个数的和输入输出格式输入格式:第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。接下来M行每行包含3或4个整数,表示一个操作,具体如下:操作1: 格式:1 x y k 含义:将...原创 2019-03-05 20:18:59 · 971 阅读 · 0 评论 -
并查集
最近做了一道最小生成树的题,用Kruskal算法,用到了并查集,这里介绍一下先看一下官方定义:并查集,在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。这一类问题近几年来反复出现在信息学的国际国内赛题中,其特点是看似并不复杂,但数据量极大,若用正常的数据结构来描述的话,往往...原创 2019-03-08 17:25:11 · 184 阅读 · 0 评论 -
克鲁斯卡尔算法 最小生成树
题目描述如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz输入输出格式输入格式:第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=5000,M<=200000)接下来M行每行包含三个整数Xi、Yi、Zi,表示有一条长度为Zi的无向边连接结点Xi、Yi输出格式:输出包含一个数,即最小生成树的各边的长度之和;如...原创 2019-03-08 16:31:38 · 818 阅读 · 0 评论 -
动态规划模板
放一个背包模板,#include<iostream>#include<cstdio>const int maxn=10002;//n表示物品个数 int f[maxn],v[maxn],val[maxn],V,n;//V表示背包体积 using namespace std;//v[]表示物品的体积, int main()//val[]表示物品的价值 { ...原创 2019-03-08 17:29:12 · 276 阅读 · 0 评论 -
大数操作
大数相加:#include<iostream>using namespace std;string Plus(string s1, string s2)//字符串做算术加法的函数{ while(s1.length()<s2.length()) s1='0'+s1; while(s1.length()>s2.length()) s2='0'+s2; bool...原创 2019-03-08 17:39:28 · 176 阅读 · 0 评论 -
二分查找
二分查找一定要是有序的才可以查找,假如我要查找一个树x,给定的序列为1 2 3 4 5 6 7 8 9,那么我判断中间一个数,假如x大于中间那个数,就表明我要找的数在序列的右半部分,小于的话就在左半部分,然后在对半个序列进行同样的操作,所以也叫二分查找,时间复杂度降到O(log2 n)下面的代码分递归与非递归两种#include<iostream>using namespa...原创 2019-03-08 17:44:41 · 136 阅读 · 0 评论 -
求回文串的个数与(马拉车算法)
回文串的个数:1 ,暴力模拟两种情况要分开讨论abc d cbaabc cba#include<stdio.h> #include<string.h> char s[5007]; int ipss(char s[]) { int len=strlen(s)-1,ans=0,l,r; for(int i=0;i<=...原创 2019-03-08 17:47:24 · 487 阅读 · 0 评论 -
快速幂取模
将指数转换为二进制,在进行操作#include<bits/stdc++.h>#define lom long longusing namespace std;lom quick(lom a,lom b,lom c){ lom ans=1; a%=c; while(b) { if(b&1) ans=ans*a%c; a=a*a%c; b>...原创 2019-03-08 17:53:23 · 118 阅读 · 0 评论 -
欧拉函数
#include<iostream>#define Max 1000001//筛选法打欧拉函数表 using namespace std; int euler(int n)//返回euler(n) { int res=n,a=n; for(int i=2;i*i<=a;i++) { if(a%i==0) { ...原创 2019-03-08 17:55:14 · 127 阅读 · 0 评论 -
全排列
#include<iostream>#include<string>#include<vector>using namespace std;bool cmp(string s,int len,int i){ for(int ii = len;ii<i;++ii) if(s[ii]==s[i]) return true; retur...原创 2019-03-08 17:56:44 · 92 阅读 · 0 评论 -
素数筛选法
这里将介绍4中方法筛选素数,并统一输出运行时间进行比较,统一用标记法,统一筛选10000005内的素数一、暴力也就是最原始的方法,从2遍历到sqrt(n)如果有一个数能被n整除,就不是素数,结果输出4.887秒,太耗时#include<bits/stdc++.h>#include<time.h>#define maxn 10000005using nam...原创 2019-03-09 12:32:10 · 379 阅读 · 0 评论 -
唯一分解定理
任何一个数都可以用素数相乘表示#include<iostream>using namespace std;int main() { int k=0; int m; while(cin>>m) { int i; for(i=2; i<m; i++) { while(m%i==0) ...原创 2019-03-09 12:31:38 · 178 阅读 · 0 评论 -
C++中那些开挂的东西
1、万能头文件#include<bits/stdc++.h>这个头文件包含了所有的头文件,以后只需要打这一个头文件就ok啦,注意hdu上只有选择G++才可以用2、加速器ios::sync_with_stdio(false);加速cin和cout,这个可以加速到像scanf一样快,but省赛好像编译出错QAQ3、扩大栈内存#pragma comme...原创 2019-03-10 20:36:11 · 906 阅读 · 3 评论 -
堆
前言:其实STL中已经定义了有关堆操作的函数:https://blog.youkuaiyun.com/qq_41431457/article/details/88573917这篇文章主要介绍一下它的原理一、什么是堆1、堆是一个二叉树,每个结点都要比两个孩子结点要大或者最小,所以根结点是二叉树中最大或最小的结点2、因为我们用树状数组来存储,所以堆也是一个完全二叉树,3、根结点是a[1],...原创 2019-03-15 14:17:11 · 219 阅读 · 0 评论 -
高精度运算
高精度是指用数组存放一个大数,然后用用一些操作来模拟加减乘除的运算加法版:#include<bits/stdc++.h> #define M 100005#define lom long longusing namespace std;int ans[M],len_a=1;void puls(lom x){ ans[1]+=x; int i=1; int t...原创 2019-03-20 19:40:14 · 196 阅读 · 0 评论 -
求最长回文字串的两种方法
1、递归:#include<iostream>#include<string>#include<algorithm>using namespace std; //递归方法,求解最长回文子序列int lps(char *str, int i, int j){ if (i == j) return 1; //只有一个元素,回文长度为1 i...原创 2019-03-08 16:43:08 · 256 阅读 · 0 评论