
算法小结
一些算法
Ctrl AC
I'm sorry for everything, everything I've done.
展开
-
【算法小结】欧拉路径与欧拉回路
欧拉路径:起点和终点不一定相同,每条边只走一次。欧拉回路:起点和终点是同一个点,每条边只走一次。原创 2022-08-12 16:57:37 · 202 阅读 · 0 评论 -
【算法小结】线段树之动态开点
pre文章:配套习题:原创 2022-08-10 13:49:38 · 117 阅读 · 0 评论 -
【算法小结】线段树之权值线段树
权值线段树:每个点存储的是 总区间内值为 l ~ r 的信息(如个数)(直接存值域)基础线段树:每个点存储的是一段下标对应区间的信息 (存定义域从而获取值域)原创 2022-08-10 10:45:07 · 117 阅读 · 0 评论 -
【算法小结】线段树之扫描树
如果当前该点.cnt==0&&该点.l!= 该点.r ,那么该点所代表的区间有效长度由子节点决定。当前结点所代表的区间包含于所要更新的区间,直接处理并return;如果当前该点.cnt==1,表明该点代表的区间全部有效。初始化每个结点所代表的区间的有效长度为零。叶结点&&cnt==0 直接清空有效长度。· 从左到右扫描边,实时更新总有效长度,并累加面积。· 对边从左到右排序,对x坐标离散化处理。否则递归处理左右结点;...原创 2022-08-10 10:26:31 · 171 阅读 · 0 评论 -
【算法小结】分块思想算法&例题(updating)
代码】【算法小结】分块思想算法&例题(updating)原创 2022-07-28 21:37:47 · 176 阅读 · 0 评论 -
【算法小结】莫队算法(基础+待修 updating)
代码过不了,数据加强了,好像只能用高级的算法,线段树树状数组...原创 2022-07-28 16:48:57 · 271 阅读 · 0 评论 -
【算法小结】优先队列使用技巧
“ Ctrl AC!一起 AC!”· 定义一个less的优先队列· 定义一个greater的优先队列然后来回在两队列队头进行反复转移,这样less会沉淀最小值,greater会沉淀最大值,而中位数就会卡在队列的队头。太妙了!!配套题目:running medium优先队列优先剔除不好的元素遍历时由条件差遍历至条件好,因为条件好可以用条件差时的值,反过来不行。当条件不满足时,优先将不好的元素值先pop掉。配套题目:click配套题目:click感谢阅读!!!“ Ctrl AC!一起 AC原创 2022-06-24 11:13:30 · 142 阅读 · 0 评论 -
【算法小结】tarjan——强连通分量的分解算法
pre文章:tarjan算法模板:配套习题:求强连通分量的个数代码:#include<bits/stdc++.h>using namespace std;const int N = 10005;vector<int> G[N];//邻接表stack<int> s;int n, m, dfn[N], ins[N], low[N], color[N], num[N], colornum, id;//结点个数,边的个数,时间戳,是否在.原创 2022-05-24 16:25:34 · 137 阅读 · 0 评论 -
【算法小结】树的重心
图片来源:树的重心笔记求树的重心有两种方法:1.根据最大连通块最小的性质求2.根据到达重心的距离之和最小的性质求(树状DP)配套题目:会议1.方法一:#include<bits/stdc++.h>using namespace std;const int N = 50005;int n, ans, sub; //结点数 树的重心 去掉某点后最大连通块的节点数int minsub = 0x3f3f3f3f; //记录最大连通块的最小值int sz[N].原创 2022-05-13 20:46:39 · 893 阅读 · 0 评论 -
【算法模板】树的直径
一般解法是两次搜索,第一次求离根节点最远的点A,第二次求里点A最远的点B。A与B之间的距离就是树的直径。#include<bits/stdc++.h>#define N 100005using namespace std;int n,d[N]={-1},deepest;vector<int> edges[N]; // vector存图void add(int u,int v) { edges[u].push_back(v); } // 简单加边void dfs(原创 2022-04-30 21:28:17 · 227 阅读 · 0 评论 -
【算法小结】带边权的最大割
“ Ctrl AC!一起 AC!”若不带边权,将边权设为1即可。步骤:枚举每个点所在集合情况,计算最大值即可。· 任取一点加入集合S中,其他的都在集合T中,然后计算此时的割,由此步开始枚举· 进入dfs进行枚举,每次枚举后计算割,并更新最大割代码:配套题目#include<iostream>using namespace std;int mp[25][25];bool inS[25];int n, maxlink;void dfs(int flowv,原创 2022-04-30 13:54:20 · 321 阅读 · 0 评论 -
Johnson 全源最短路
“ Ctrl AC!一起 AC!”步骤:· 对于原图,新增一个结点s,使该点与所有点之间建立一条边,权重为零。· 对新图使用bellman或spfa求得新点s到其他点的最短距离,h[0]....h[V-1]· 对原图进行边权更新,w`(u,v)=w(u,v)+(h[u]-h[v])· 移除新的顶点s,以每个顶点为起点求出最短路代码:配套题目:Johnson#include <cstring>#include <iostream>#include原创 2022-04-29 14:57:01 · 350 阅读 · 0 评论 -
【算法模板】拓扑排序
可以使用邻接矩阵或邻接表步骤: 初始时,先第一遍扫描入度为零的点,存入队列中 以该点为父点,通过邻接矩阵遍历他的所有子点 子点的入度减一,并对该点进行处理(如求最长路,可以通过父点更新他到起点的长度,或如求从起点到该点的路数,即可以累加上父点的路数) 当子点的入度为零时,将他加入到队列中 循环直到队列为空 模板题1:P4017 最大食物链计数#include<bits/stdc++.h>using namespace std;con原创 2022-04-25 22:04:25 · 192 阅读 · 0 评论 -
【算法模板】pair版堆优化·链式前向星·Dijkstra
“ Ctrl AC!一起 AC!”对不起,本蒟蒻只会背模板...qwqdijkstra一般用来解决单源最短路径问题,可以通过堆优化省去第二层找最近的那个点的循环。pair版堆优化开始用队列存储起点,然后利用优先队列对dis自动排序的功能,取出队头即为所要的最近点typedef pair<int, int> PII; //first->distance; second->u;priority_queue<PII, vector<PII>,原创 2022-04-23 22:58:46 · 1648 阅读 · 0 评论 -
线段树笔记
线段树学习笔记参考基本概念线段树的每个节点维护一个区间[i, j]的信息。如果一个节点维护着区间[i, j]的信息,且i != j,那么其左孩子维护着区间[i, (i+j)/2]的信息,右孩子维护着区间[(i+j)/2+1, j]的信息。线段树中,如果一个节点的编号为x,那么左孩子的编号为2x,右孩子的编号为2x+1。数组长度通常开最大长度的4倍建树每颗树的叶结点都是数组中的一个值,由叶结点自底向上推出父节点,注意这里的树也就是个扩大四倍的数组例:建一个线段区间最小值树//线段树数组:原创 2022-04-04 20:53:07 · 386 阅读 · 0 评论 -
【算法小结】大整数快速幂
“ Ctrl AC!一起 AC!”前置文章:【算法小结】快速幂基于普通版快速幂,大整数快速幂的数值范围要大于long long 类型,所以我们在处理指数时,要分段处理:例如:将指数123分解成3+10*2+100*1,所以关键点就是不断以十次幂扩大底数然后对右式分析:其中a^3,a^10,(a^10) ^2,....都可以通过普通版的快速幂实现#include<bits/stdc++.h>using namespace std;typedef long lo原创 2022-04-03 23:12:58 · 430 阅读 · 0 评论 -
【算法小结】尺取法及例题(Subsequence,Jessica’s Reading Problem)
“ Ctrl AC!一起 AC!”反复地推进区间的开头和末尾,来求取满足条件的最小区间的方法被称为尺取法目录例1:Subsequence解法1:解法2(尺取法):例2:Jessica's Reading Problem解(尺取法):例1:Subsequence解法1:用sum[i]表示区间[0,i)的整数和,那么sum[t]-sum[s]就是区间[s,t)的整数和a(0)+...+a(i-1)=sum[i]a(s)+...+a(t-1)=.原创 2022-04-02 23:24:47 · 706 阅读 · 0 评论 -
最长公共/上升/公共上升子序列
目录最长上升子序列:最长公共子序列:最长公共上升子序列:“ Ctrl AC!一起 AC!”最长上升子序列:设序列为s,则dp[i] 表示以s[i]结尾的序列中的最长上升子序列的长度状态方程:dp[i]=max(dp[j]+1) (其中j<i,并且s[j]<s[i])核心代码(s下标从零开始):for(int i=0;i<len;i++){ for(int j=0;j<i;j++){ if(s[j]<s[i]) dp[i+1]=ma原创 2022-03-31 23:05:01 · 304 阅读 · 0 评论 -
【算法小结】多重集组合数---DP
“ Ctrl AC!一起 AC!”问题:有n种物品,第i种物品有x[i]个。不同种类的物品可以互相区分但相同种类的物品不可区分。从这些物品中取出m个的话,有多少种取法?求出方案数模M的余数。分析:设dp[i][j]表示从i种物品中取出j件的方案数。如果要从i种物品中取出j件,我们可以先从i-1中物品中取出j-k件,再从第i中物品中取出k件。复杂度为O(nm^2),可继续优化。· j<=x[i]时展开式子可得:dp[i][j] = dp[i-1][j] + dp[i-原创 2022-03-24 18:24:06 · 691 阅读 · 0 评论 -
【算法小结】划分数---计数DP
“ Ctrl AC!一起 AC!”问题:有n个无区别的物品,将它们划分成不超过m组,求出划分方法数模M的余数。定义dp[i][j]表示将j个物品划分成i组的总方案数。· 若这i组里每个组的总数量大于零,那么 若每组的数量都减去1,那么j就变成了j-i· 若这i组里面存在一个总数量等于零的组,那么这个组可有可无递推公式:dp[i][j]=dp[i][j-i]+dp[i-1][j]代码实现:int n,m;int dp[MAXN][MAXN];void so原创 2022-03-23 19:44:15 · 254 阅读 · 0 评论 -
【算法小结】多重部分和问题
“ Ctrl AC!一起 AC!”目录多重部分和问题:解法一:解法二:多重部分和问题:有n种不同大小的数字a_i,每种各m_i个。判断是否可以从这些数字之中选出若干使它们的和恰好为K。解法一:定义dp[i][j],表示用前i种数字是否能加成j。要让前i种数字加和成j,那么就要让前i-1种数字加和成j,j-a_i ... j-m_i*a_i 中的某一种。#include<bits/stdc++.h>using namespace std;c原创 2022-03-22 20:21:36 · 366 阅读 · 0 评论 -
【算法小结】树状数组及其应用
“ Ctrl AC!一起 AC!”目录根据原数组求树状数组:通过树状数组求前缀和:更新树状数组以更新原数组:实例:根据原数组求树状数组:首先树状数组的下标的是从1开始!通过树状数组求前缀和:int getSum(int x){ int sum=0; for(int i=x;i>0;i-=lowbit(i)){ sum+=c[i]; } return sum;}更新树状数组以更新原数组:void updat...原创 2022-03-19 17:39:22 · 214 阅读 · 0 评论 -
【算法小结】并查集
并查集实现方式:数组:int father[N]其中father[i]表示i的父结点,father[i]=[i]时说明i是该集合的根并查集基本操作:1.初始化father数组:for(int i=1;i<=n;i++) father[i]=i;2.查找根结点:int findFather(int x){ while(x!=father[x]) x=father[x]; return x;}3.合并两个不同的集合:将一个集合的根节点指向另一个集合的根节点原创 2022-03-05 22:53:40 · 268 阅读 · 0 评论 -
【算法小结】lowbit运算
“ Ctrl AC!一起 AC!”lowbit运算:lowbit(x)=x&(-x)整数在计算机中是以补码形式存储的,把一个补码表示的整数x变成其相反数-x相当于· 把x的二进制的每一位都取反,然后末位加1或· 直接把x的二进制最右边的1的左边的每一位都取反所以lowbit(x)=x&(-x) 就是取x的二进制最右边的1和它右边的所有0因此它一定是2的幂次所以lowbit(x)也可以理解为能整除x的最大2的幂次例:分别.原创 2022-03-03 22:36:38 · 309 阅读 · 0 评论 -
【算法小结】背包问题
“ Ctrl AC!一起 AC!”【本文仅用于记录结论】0-1背包:普通模式:状态方程:dp[i][v]=max{dp[i-1][v],dp[i-1][v-w[i]]+c[i]}边界:dp[0][v]=0for(int i=1;i<=n;i++){ for(int v=w[i];v<=V;v++){ dp[i][v]=max(dp[i-1][v],dp[i-1][v-w[i]]+c[i]); }}空间压缩模式:状态方程:dp[v]=max{dp[v],原创 2022-03-02 22:04:04 · 114 阅读 · 0 评论 -
【算法小结】Mex,SG,集合-Nim游戏模型
Mex运算:定义Mex(S)表示不属于集合S的最小非负整数。SG函数:在有向图游戏(先手从起点出发,到达某点,接力给后手操作,轮流进行,谁操作后到达终点谁赢)中,对于每个结点x出发共有k条有向边,分别到达结点y1,y2 ... yk,定义SG(x)表示y1到yk的SG值构成的集合进行Mex运算后的结果:SG(x)=mex{SG(y1),...,SG(yk)}特别地· 整个有向图(G)游戏的SG值定义为有向图起点s的SG值:SG(G)=SG(s)· 终点的SG值定义为零。原创 2022-03-02 18:19:39 · 3694 阅读 · 0 评论 -
【算法小结】组合数的计算
“ Ctrl AC!一起 AC!”本文主要解决两个问题:1.如何计算C(n,m)2.如何计算C(n,m)%p1.C(n,m)的计算方法一:通过定义式计算C(n,m)=n!/m!/(n-m)!只能计算n<=20的数据long long C(long long n,long long m){ long long ans=1; for(long long i=1;i<=n;i++){ ans*=i; } for(long long i=1;i<=m;原创 2022-02-27 22:58:08 · 348 阅读 · 0 评论 -
【算法小结】扩展欧几里得
“ Ctrl AC!一起 AC!”声明:本博客主要记录结论,证明较少,需要证明自行转往扩展欧几里得算法目录1.基本的扩展欧几里得算法2.ax+by=c的求解3.同余式(mod m)的求解4.逆元的求解以及(b/a)%m的计算1.基本的扩展欧几里得算法扩展欧几里得算法用来解决这样一个问题:给定两个非零整数a和b,求一组整数解(x,y),使得ax+by=gcd(a,b)。int exGcd(int a,int b,int &x,int &y){.原创 2022-02-26 21:34:08 · 375 阅读 · 0 评论 -
【算法小结】费马小定理
“ Ctrl AC!一起 AC!”费马小定理可以用来求乘法逆元。费马小定理:P为质数时且gcd(A,P)==1,则A^(P-1)=1(在mod P的条件下)。乘法逆元:A*B=1(mod P情况下),A与B互为乘法逆元。所以当 P为质数时且gcd(A,P)==1 时:A*B=A^(P-1) ---> B=A^(P-2)这样只要对A^(P-2)来个快速幂,就能得出A的乘法逆元#include<bits/stdc++.h>using namespace st原创 2022-02-25 10:03:39 · 701 阅读 · 0 评论 -
【算法小结】快速幂
“ Ctrl AC!一起 AC!”目录递归快速幂:迭代快速幂:递归快速幂:递归快速幂基于以下两点展开:1.如果b是奇数:那么有a^b=a*a^(b-1)2.如果b是偶数:那么有a^b=a^(b/2)*a^(b/2)递归快速幂模板:typedef long long LL;LL binaryPow(LL a,LL b,LL m){ //(a^b)%m if(b==0) return 1; if(b%2==1) return a*binaryPow(a,b-1原创 2022-02-23 22:04:50 · 206 阅读 · 0 评论 -
【算法小结】分解质因数
“ Ctrl AC!一起 AC!”质因数分解:将一个整数n写成一个或多个质数的乘积形式,例如:180=2*2*3*3*5 。结论:对一个整数n来说,如果它存在[2,n]范围内的质因数,则最多只存在一个大于sqrt(n)的质因数,而其他质因子全部小于等于sqrt(n)。思路:枚举1~sqrt(n)范围内的所有质因子p,判断p是否是n的因子。·如果是,就将它加入到质因子结构体数组中,并初始其个数为0,然后只要p还是n的因子,就让n不断除以p,每次操作个数加一,知道p不再是n的因子。·如果不是原创 2022-02-22 11:45:46 · 595 阅读 · 0 评论 -
【算法小结】kruskal
“Ctrl AC!一起 AC!”kruskal是解决最小生成树问题的一种方法。基本思路:每次选择图中最小边权的边,如果边两端的顶点在不同的连通块(最开始,每个点就是一个连通块,随着边的选择而连接),就把这条边加入到最小生成树中;否则扔掉。边的定义:struct edge{ int u,v; //边的两个端点 int cost; //边权}E[MAXV];对边排序(sort里的cmp函数):bool cmp(edge a,edge b){ return a.cost&l原创 2022-02-21 21:37:07 · 133 阅读 · 0 评论 -
【算法小结】prim
“ Ctrl AC!一起 AC!”prim用来解决最小生成树问题。主要操作如下:首先设置一个集合S,存放已访问的点,初始为空。执行n次(n为顶点的个数)一下两个操作:1.每次从未访问的点中选择与集合S最近的一个顶点(记为u),访问u,并加入S,同时将这条到达u的边加入最小生成树。2.利用点u,优化未访问的点与集合S之间的最短距离。邻接矩阵版:int n,G[MAXV][MAXV]; //n为顶点数int d[MAXV]; //顶点与集合S之间的最小值bool vis[M原创 2022-02-20 21:11:30 · 433 阅读 · 0 评论 -
【算法小结】Floyd
“ Ctrl AC!一起 AC!”Floyd算法用来解决全源最短路径问题:给定图,求任意两点间的最短路径。该算法一般用邻接矩阵解决。核心思想:如果存在点k使得点i,j之间的距离更短,那么就更新i,j之间的距离,dis[i][j]表示i,与j之间的距离。即:if(dis[i][k]+dis[k][j]<dis[i][j]) then dis[i][j]=dis[i][k]+dis[k][j]const INF=1000000000;const int MAXV=200;int原创 2022-02-20 20:21:23 · 562 阅读 · 0 评论 -
【算法小结】Bellman-Ford & SPFA
“ Ctrl AC!一起 AC!”Bellman-FordBellman-Ford算法可以很好解决有负权边的最短路径问题,与Dijkstra算法不同的是,这个算法函数需要返回一个bool值,表示从源点出发,是否存在一条返回到自己的环,且环的权和为负值。主要操作:进行n-1次(n为顶点)如下操作:遍历所有的边u->v,如果以u为中介点,能够更新d[v]的话,就更新(d[v]表示从起点到点v的最短距离)。进行完上述操作后,最后进行一遍如下操作:遍历所有的边u->v,如原创 2022-02-19 16:00:52 · 665 阅读 · 0 评论 -
【算法小结】Dijkstra+DFS
“ Ctrl AC!一起 AC!”回顾之前的Dijkstra算法,会发现,算法中的数组pre总是保持着最优路径,当出现多种边权时需要严谨的判断才能对pre进行正确的更新。这里我们可以用更简单的方法:先在Dijkstra算法中记录下所有最短的路径,然后从中选出一条第二尺标最优的路径。第一步:使用Dijkstra算法记录所有最短路径因为要记录所有最短路径,那么每个点的前驱节点可能有多个,我们可以定义一个容器数组:vector<int> pre[MAXV],这样就能记录每个点的所有原创 2022-02-18 10:00:32 · 400 阅读 · 1 评论 -
【算法小结】Dijkstra迪杰斯特拉算法
“ Ctrl AC!一起 AC!”目录ONE.求起点到达其他点的最短距离TWO.求具体的最短路径THREE.求最短路径共有几条FOUR.考虑新增边权或点权求最优Dijkstra一般用于解决单源最短路问题ONE.求起点到达其他点的最短距离策略:设置集合S存放已访问的顶点,然后进行若干次以下操作,直到点全访问完毕。1.每次从未访问的点中选择一个距离起点最近的点,加入S。2.以新加入的点为介点进行路径优化。具体实现:1.bool型vis数组表示某点有没有访问过。原创 2022-02-17 22:01:43 · 788 阅读 · 0 评论 -
【算法小结】散列
“ Ctrl AC!一起 AC!”目录1.key是整数:2.key是字符串:前言:将数据直接当作数组的下标进行记录便是最广义的散列。散列的浓缩定义:“将元素通过一个函数转化成一个整数,使得该整数可以尽量唯一地代表这个元素。其中把这个转换函数称为散列函数H。元素转换前叫key,转换后可表示为H(key)。1.key是整数:最常见散列函数---除留余数法:将key除以一个数mod,再取得到的余数作为哈希值。H(key)= key % mod数组大小Tsize为原创 2022-02-16 20:28:52 · 325 阅读 · 2 评论 -
【算法小结】堆及堆排序
“ Ctrl AC!一起 AC!”目录堆堆排序堆堆是一颗完全二叉树,其中树的每个结点都不小于其左右孩子的称为最大堆,反之称为最小堆。【以下以最大堆为例】定义数组表示堆:const int maxn=100;//heap为堆,n为元素个数int heap[maxn],n=10;向下调整://low为欲调整的下标,high为最后一个元素的下标void downAdjust(int low,int high){ int i=low,j=i*2; while原创 2022-02-14 19:55:28 · 333 阅读 · 0 评论 -
【算法小结】KMP及扩展KMP
“ Ctrl AC!一起 AC!”目录next数组:KMP算法1.判断模式串是否为文本串的子串2.判断模式串在文本串中出现次数nextval数组:扩展KMP算法:next数组:next[i]表示一个字符串的0到i处的子串的最长的相同的前后缀(可以重叠)的【中前缀】的最后一个字符的下标。求next数组模板:void getNext(char s[],int len){ int j=-1; next[0]=-1; for(int i=1;i<len;原创 2022-02-11 17:14:37 · 787 阅读 · 0 评论