ACM模板
文章平均质量分 60
ACM模板
daq0411
这个作者很懒,什么都没留下…
展开
-
优先队列定义排序方式
1.按照从大到小进行排序priority_queue<int>q1;priority_queue<int,vector<int>,less<int> >q2;//注意less<int>和最后一个>要加空格分隔开struct infor{ int a,b; friend bool operator < (infor x,infor y){ return x.a < y.a; }}priority_queue<原创 2021-04-13 20:08:31 · 448 阅读 · 0 评论 -
线段树
Structure 数据结构线段树先贴代码,日后一定补(狗头保命),还有区间乘,联系树状数组一起写一篇完整的。B站一位大佬讲的很清楚:B站连接#include<iostream>#include<cstring>using namespace std;typedef long long ll;ll shu[200001];ll ans[200001];ll tag[200001];int n;void build(int p,int l,int r){ if原创 2021-02-03 22:59:32 · 54 阅读 · 0 评论 -
KMP算法
String 字符串KMP算法KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)。void get_next(string s){ int k = -1; next[0] = -1原创 2021-01-29 18:54:43 · 96 阅读 · 1 评论 -
次小生成树 Kruskal
Graph 图论次小生成树 Kruskal1、初始化:对并查集进行初始化;for(int i=1;i<=n;i++){ f[i] = i;}对vis数组初始化;对graph数组进行初始化for(int i=1;i<=n;i++) { graph[i].clear(); graph[i].push_back(i); }2、对边进行排序;sort(map,map+m,cmp);3、判断当前边的两个节点是否已经属于同一集合,如果不属于:①这条边标记为使用;②把这两个点所在的集合统一为原创 2021-01-27 23:29:38 · 176 阅读 · 0 评论 -
次小生成树 Prim
Graph 图论次小生成树 Prim我们最常见的是最小生成树,我们最长使用的是Prim和Kruskal算法,一个是对点进行处理,一个是对边进行处理,对于次小生成树来说我们同样可以使用这两个方法进行处理,这里我们先以Prim的写法为例。首先我们要清楚的是什么是最小生成树:一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。所以在这之前我们需要先了解几个结论:①如果我们要换掉其中的一条边的话新得到的生成树的权值之和一定小于等于原最小生成树的原创 2021-01-26 23:56:03 · 175 阅读 · 3 评论 -
String的最短重复字段
String 字符串String的最短重复字段今天做codeforces遇到的一道题,感觉很有意思,虽然有更好的做法,但是为例找一下最短重复子串也是挺有意思的。原题连接:https://codeforces.com/contest/1473/problem/B我们在这里就说一下找一个字符串的最短重复字段吧,假设一个字符串s的字符长度是10,那么他的重复字段的长度就是1,2,5,10这几种情况,比如说aaa,他就是由字段a重复构成;bcbcbc,它由子段bc重复构成;abc除了他本身就没有其他子序列重原创 2021-01-24 19:19:12 · 449 阅读 · 0 评论 -
kruskal 最小生成树
Graph 图论kruskal 最小生成树相对于prim算法对于图中的点进行处理,kruskal则是对于边进行处理,我们在使用kruskal进行处理的时候,需要用到并查集的思想,后面我们会说。kruskal算法实现的大致思路是先对边进行从小到大排序,如果这条边的起点和终点已经在一个集合了,说明加上这条边不会增加新的点对于当前这两个点所在的集合,如果这两个点属于同一个集合,那么把这条边连起来之后会让两个集合变成同一个集合(我们的目的不就是把所有点通过边归到一个集合里面吗),重复此操作直到加入集合的点达到原创 2021-01-24 12:28:27 · 274 阅读 · 0 评论 -
Prim 最小生成树
Graph 图论Prim 最小生成树其实最小生成树的写法跟Dijkstra很类似,就是需要改一个地方就可以:if(dist[b.to]>b.cost){ dist[b.to] = b.cost; }Dijkstra的写法是if(dist[b.to]>dist[node]+b.cost){ dist[b.to] = dist[node]+b.cost; }其他的都一样,因为Dijkstra需要计算的是从源点出发到每个点的最短距离,所以我们需要的是边的长度之和,而最小生成树的原创 2021-01-24 10:07:27 · 94 阅读 · 1 评论 -
高斯消元
Number 数论高斯消元数学上,高斯消元法(或译:高斯消去法),是线性代数规划中的一个算法,可用来为线性方程组求解。但其算法十分复杂,不常用于加减消元法,求出矩阵的秩,以及求出可逆方阵的逆矩阵。不过,如果有过百万条等式时,这个算法会十分省时。一些极大的方程组通常会用迭代法以及花式消元来解决。当用于一个矩阵时,高斯消元法会产生出一个“行梯阵式”。高斯消元法可以用在电脑中来解决数千条等式及未知数。亦有一些方法特地用来解决一些有特别排列的系数的方程组。消元法是将方程组中的一方程的未知数用含有另一未知数的代原创 2021-01-23 20:40:26 · 298 阅读 · 0 评论 -
dijkstra + A* 第k短路
Graph 图论第k短路今天好懒啊,不想补了……但是怕忘了,先把笔记挂上日后补上吧(狗头保命),但是启发式搜索的确挺有意思的一个算法。(一定补一定补)#include<iostream>#include<queue>#include<vector>#include<cstring>using namespace std;int n,m,begin,end,k;struct edge{ int b; int cost;};vector原创 2021-01-22 21:15:20 · 179 阅读 · 0 评论 -
Dijkstra最短路计数
Graph 图论Dijkstra最短路计数我们最常用的dijkstra是来算单源最短路径,也就是最短路径的长度,如果我们要计算最短路的条数呢?我们只需要在dijkstra算法上稍加更改即可。例如我们a->b->c的路径长度是x,a->d->c的路径长度也是x,所以这两条路径到达c点的距离相等,我们可以很直观的直到到达c的最短路的条数是2,如果还有一条道路c->e,那么我们也很容易得知到达e的最短路径条数也是2这是一个简单的例子,我们可以很直观的看出,通过这个例子我们可原创 2021-01-22 21:04:24 · 2224 阅读 · 2 评论 -
Dijkstra 最短路还原路径
Graph 图论Dijkstra 最短路还原路径Dijkstra链接我们求最短路最常用的就是dijkstra算法,然而我们在很多时候需要打印出这条最短的路径,这时我们就要想一个办法来保存路径,这里我们借助一点点类似于并查集的思想,就是用一个path数组来存储从原点开始到达这个点的最短路径的上一步,简单来说就是我们从哪个点到的这个点,举个例子吧:假设我们已经知道 a->b->c->d 是a到d的最短路,那么d是由谁到达的呢?显然是c,那么我们就令path[d] = c;,同理path原创 2021-01-21 19:54:42 · 138 阅读 · 0 评论 -
Floyed算法(任意两点间的最短路)
Graph图论Floyed算法(任意两点间的最短路)可以处理存在负边的情况,也可以判断是否存在负环。对于最短路我们之前接触的都是单源最短路径,即起点固定,求该点开始到其他点的最短路径,但是如果我们想要求得任意两点间的最短路径,难道要对每一个点都要进行一遍dijkstra?显然比较麻烦,并且还不好存储信息,那么我们就要用到Floyed算法了。在这里我们用到一个dp数组dp[ i ][ j ]:从 i 到 j 所需要的最短距离,其实把数组的作用想明白了算法也就完成了大半,那么我们假设有一个点k,那么我们原创 2021-01-21 19:13:20 · 418 阅读 · 0 评论 -
SPFA
Graph 图论最短路(SPFA)若图中存在负权边,这时Dijkstra算法便不能再使用,而Bellman-Ford算法的复杂度又过高(O(V * E)),SPFA便能很好的优化Bellman_Ford的时间复杂度。我们可以在执行该算法前做一次拓扑排序,以判断是否存在负权回路。类似于Bellman_Ford算法,我们不能像Dijkstra那样对点进行处理,前面我们已经学习了dijkstra算法来求最短路,但是dijkstra有一个很大的问题就是无法计算有负权值的图,这是因为dijkstra找到一个当前原创 2021-01-21 15:44:26 · 93 阅读 · 0 评论 -
最短路(Bellman_Ford)
Graph 图论最短路(Bellman_Ford)缺点:不能计算包含负环的图前面我们已经学习了dijkstra算法来求最短路,但是dijkstra有一个很大的问题就是无法计算有负权值的图,这是因为dijkstra找到一个当前dist最小点的时候便将该点设置为已访问,便不再处理该点,这对边权为非负数的时候适用,因为该点的权值不会再被更新(dijkstra),然而如果一个图的边带有负权值,那么该算法便不再适用,因为即使是当前dist最小的点之后还有可能会被负值所更新,所以我们就不能像dijkstra那样原创 2021-01-21 08:24:46 · 83 阅读 · 0 评论 -
最短路(Dijkstra)
Graph 图论1、最短路1、Dijkstra单源最短路(二维数组)首先我们需要这样几个数组:vis[ i ]:编号为 i 的节点是否被访问,被访问过了置为1,没有就置为0,源点的vis值置为1,因为从他本身开始走,本身肯定是被访问过;dist[ i ]:从源点开始到编号为 i 的点的最短路径,源点的dist值置为0,因为从他自己开始到他自己本身的距离就是0;map[ i ][ j ]:从 i 到 j 的道路的长度,如果从 i 到 j 没有道路,道路长度置为INF;我们的准备工作做好了我们就原创 2021-01-20 16:43:34 · 859 阅读 · 0 评论 -
编辑距离
String 字符串1、编辑距离编辑距离,又称Levensgtein距离(莱文斯坦距离也叫做Edit Distance),是指两个字符串之间,有一个转成另一个字符串所需要的最小编辑操作的次数,编辑操作次数包括替换一个字符,添加一个字符,删除一个字符,如果它们的距离越大,说明它们越是不同。...原创 2021-01-20 10:04:18 · 213 阅读 · 0 评论 -
组合数学相关
Number数论组合数学相关排列问题排列数从n个不同元素种取出m(m≤n)个元素的所有不同排列的个数,叫做从n个不同元素种取出m个元素的排列数,用A(n,m)表示。排列数公式A(n,m) =n (n−1) (n−2) ⋯ (n−m+1) = n! / (n−m)!,n,m∈N+,并且m≤n(规定0!=1)推导:把n个不同的元素任选m个排序,按计数原理分步进行取第一个:有n种取法;取第二个:有(n−1)种取法;取第三个:有(n−2)种取法;……取第m个:有(n−m+1)种取法原创 2021-01-18 23:38:08 · 596 阅读 · 0 评论 -
欧几里得算法
Number 数论欧几里得算法百度百科:欧几里得算法又称辗转相除法,是指用于计算两个非负整数a,b的最大公约数。应用领域有数学和计算机两个方面。计算公式gcd(a,b) = gcd(b,a mod b)。假如需要求 1997 和 615 两个正整数的最大公约数,用欧几里得算法,是这样进行的:1997 / 615 = 3 (余 152)615 / 152 = 4(余7)152 / 7 = 21(余5)7 / 5 = 1 (余2)5 / 2 = 2 (余1)2 / 1 = 2 (余0)至此原创 2021-01-18 18:39:53 · 5423 阅读 · 0 评论 -
筛法欧拉函数
Number数论欧拉函数PHI筛法欧拉函数欧拉函数在数论,对正整数n,欧拉函数是小于或等于n的正整数中与n互质的数的数目(因此φ(1)=1)。此函数以其首名研究者欧拉命名(Euler’s totient function),它又称为Euler’s totient function、φ函数、欧拉商数等。 例如φ(8)=4,因为1,3,5,7均和8互质。 从欧拉函数引伸出来在环论方面的事实和拉格朗日定理构成了欧拉定理的证明。链接: link....原创 2021-01-17 11:50:33 · 176 阅读 · 0 评论 -
分解质因数法
Number数论欧拉函数1.1 分解质因数法输出一个数的所有质因数,例如8 = 2 * 2 * 2;#include<iostream>using namespace std;int main(){ int n; cin >> n;//分解N cout << n << " = "; for(int i=2;i<=n;i++){//遍历小于等于n的所有数 while(i!=n){ if(n%i==0){ n /= i原创 2021-01-17 11:30:03 · 425 阅读 · 0 评论 -
根据先序序列和中序序列得到后序序列(C语言
#include<stdio.h>//pre前序序列,zhong中序序列,pos后序序列int pre[100],zhong[100],pos[100];int n,t; //找到元素K在中序序列中的位置int find(int k,int s,int e){ for(int i=s;i<=e;i++) if(zhong[i] == k) return i;}//转化为后序序列void to_hou(int zs,int ze,int p原创 2020-05-13 17:37:03 · 1361 阅读 · 0 评论