随笔分类 - 我的算法模板
-
基础数论--卡特兰数
摘要:1 #include<iostream> 2 using namespace std; 3 typedef long long LL; 4 const int mod=1e9+7; 5 LL qmi(LL a,LL b,LL mod){ 6 LL res=1; 7 while(b){ 8 if(b& 阅读全文
-
基础数论--组合数
摘要:C(a,b)表示从a中选b个苹果,0<=b<=a n代表询问次数 根据不同的数据范围有不同的解法 1、1≤n≤10000,1<=b<=a<=2000 此时n较大,询问次数较多,而a,b较小,可以预处理出所有C(a,b)的值,然后进行查询 用到了公式C(a,b)=C(a-1,b-1)+C(a-1,b) 阅读全文
-
基础数论--高斯消元
摘要:高斯消元是线性代数的一种算法,可用来求解线性方程组问题。 线性方程三大基本操作: 1)两方程互换,解不变; 2)一方程乘以非零数k,解不变; 3)一方程乘以数k加上另一方程,解不变 例题1:https://www.acwing.com/problem/content/885/ 1 #include< 阅读全文
-
基础数论--例题
摘要:题目链接:https://www.acwing.com/problem/content/206/ 推导过程: 存疑处也就是不知如何从在求出x*a+y*b=m同余方程的一个解的情况下求出x和y的通解。 补充:假设求的x=x1,y=y1 那么ax1+by1=m ax1+by1+kab-kab=m(k为整 阅读全文
-
基础数论--扩展欧几里得算法
摘要:正常的欧几里得算法 1 int gcd(int a,int b){ 2 return b==0?a:gcd(b,a%b); 3 } 可以在O(n)的时间复杂度内,求出a和b两数的最大公约数。 而扩展欧几里得算法则可以在求出最大公约数的同时,求出两个数x,y,使得x*a+y*b=gcd(a,b),用处 阅读全文
-
基础数论--欧拉定理,逆元
摘要:1、欧拉定理 欧拉定理,若a与p互质,那么a ^ (phi[n]) ≡ 1 (mod n) 证明:假设x1,x2....x(phi[n])是1~n中与n互质的数 可以发现,他们是两两不同的。 将每个数都乘以a,得ax1,ax2....ax(phi[n]) 假设我们已经证明在mod n的情况下,x1* 阅读全文
-
基础数论--快速幂
摘要:正常求a^b的方法是迭代,但是效率太低,时间复杂度为O(n) 所以就有了快速幂的诞生 快速幂的基本思想是二进制。将指数用化为二进制表示,那么就只剩下logb + 1位,然后如果能够在小于O(logn)的时间复杂度内建立出一张2^0~2^(log b +1)的表的话,就能在O(log n)的时间复杂度 阅读全文
-
基础数论--欧拉函数
摘要:在数论,对正整数n,欧拉函数是小于或等于n的正整数中与n互质的数的数目(因此φ(1)=1) 互质指的就是gcd(a,b)=1。 所以对于某个数n,求他的欧拉函数可以直接用暴力。 1 int gcd(int a,int b){ 2 return b==0?a:gcd(b,a%b); 3 } 4 int 阅读全文
-
基础数论--约数
摘要:1、试除法求约数 朴素想法是直接枚举1-n,如果n%i==0,i就是约数 但是考虑到约数是成对出现的,假设i是n的约数,那么n/i也是n的约数,所以只需要枚举到sqrt(n)即可 时间复杂度为:sqrt(n),需要证明排序的复杂度小于求约数的复杂度 排序复杂度是nlogn,那么我们就得知道n有多少个 阅读全文
-
数论基础--质数
摘要:质数定义:只有1和本身两个约数的数称为质数(或素数) 1、试除法判断质数 根据定义,对于某个数n,枚举2-n-1,看是否能够整除,以此判断是否为质数 但是因为因子是成对出现的,所以只需要枚举到<=sqrt(n)即可 1 //时间复杂度sqrt(n) 2 #include<iostream> 3 us 阅读全文
-
图算法--二分图的最大匹配(匈牙利算法)
摘要:二分图的最大匹配的意思就是给定一个二分图,找出最多的边,使得一个点不会同时在两条边的端点上。 举个例子就是,有一堆男生和一堆女生,每个男生和某些女生相互之间有一定的好感度,我们作为月老,秉持宁拆一座庙,不毁一桩婚的原则,希望最后的配对数目最多。 而匈牙利算法就是解决这样一个问题的算法。 匈牙利算法的 阅读全文
-
图算法--染色法判定二图
摘要:二分图的定义是可以把一个图的点分成两个集合,使得集合内部没有边 可以证明如果一个图可以被2染色,那么它就是一个二分图 1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 const int N=1e5+10,M=2*N; 阅读全文
-
图算法--kruskal
摘要:kruskal算法的时间复杂度瓶颈在排序上 1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 int n,m; 5 const int N=1e5+10,M=2e5+10,INF=0x3f3f3f3f; 6 str 阅读全文
-
图算法--最小生成树prim
摘要:思路类似于dijkstra,只不过松弛的时候略微不同,松弛成到已经确定的任一点的最短距离,而dijkstra则是松弛为到起点的最短距离 1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 const int N=510, 阅读全文
-
图算法--判负环
摘要:bellman-ford判负环,据bellman-ford的性质最后得出的是通过不超过n-1条边的从起点到其他点的最短距离(因为n个点,所以n-1条边) 但是如果在n-1次循环之后仍然存在边可以被松弛,那么就存在负环(因为如果没有负环n-1次就已经确定了最短距离,具体可参考bellman-ford证 阅读全文
-
图算法--floyd
摘要:floyd是用来解决多源最短路的 其核心思想是动态规划,d[ k , i , j ] 表示以不超过k的点为中间点从 i 到 j 的最短距离 d[k , i , j ]=min(d[k-1 , i , j ] ,d[k-1 , i ,k ]+d[k-1, k , j ]); 为了保证k的状态都是从k- 阅读全文
-
图算法--spfa
摘要:spfa的最坏时间复杂度是O(nm),但是一般达不到这么高 spfa是bellman-ford算法的升级版,bellman-ford是每次对所有的边判断是否可以松弛,但是实际上只有从刚刚松弛的点出发的边才有可能松弛其他点 所以就可以省去很大一部分的判断 1 #include<iostream> 2 阅读全文
-
图算法--bellman-ford (nm)
摘要:bellman-ford是一个可以求带负权边的单源最短路,但是时间复杂度是铁定的O(nm),所以我们一般用他的优化版本SPFA,不过由于bellman-ford算法的流程,它也可以用来解决一类特定的问题 那就是求出起点到其他点经过不大于k条边的最短路径 1 #include<iostream> 2 阅读全文
-
图算法--堆优化版dijkstra
摘要:单源最短路+正权图+稀疏图 >堆优化dijkstra 1 #include<iostream> 2 #include<vector> 3 #include<cstring> 4 #include<queue> 5 using namespace std; 6 int n,m; 7 const int 阅读全文
-
图算法--朴素版dijkstra
摘要:单源最短路+正权图+稠密图 >朴素版dijstra 1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 const int N=510; 5 int g[N][N],dis[N]; 6 bool st[N]; 7 int 阅读全文