算法
文章平均质量分 57
不见月光见星光
这个作者很懒,什么都没留下…
展开
-
带权并查集
一 基础的并查集对于基础的并查集而言,只存在着两种操作,一种是寻找祖先一种是进行合并int find(int x){ if(x==pre[x]) return x; else return pre[x]=find(pre[x]);}void join(int x,int y){ pre[find(x)]=find(y);}二 带权并查集 对于带权并查集而言,它可以在我们的基础并查集上去维持一定的其他关系,比如距离等,在这里我们以杭电~HDUyyds的How Man原创 2021-11-03 20:22:13 · 866 阅读 · 0 评论 -
前缀和优化dp
在我们编写dp方程尤其是在区间dp的方程之中,我们经常能够使用到前缀和其进行优化,主要的原因是在于在进行区间dp的时候,有时候是对前面一层状态的一个累加,在这个时候我们完全可以使用前缀和对它进行优化,不过要注意的就是这个区间的边界问题 下面我们来看一道板子题,出门左转 对于这个板子题的意思我们很容易了解,就是在找到逆序对数目为k的排列的数目. 对于这个排列,我们可以得到这样一个方程 f[i][j]=∑k=j−i+1jf[i−1][k]f[i][j] = \sum_{k=j-i+1}^{j}f[i-1原创 2021-10-31 14:57:46 · 399 阅读 · 0 评论 -
二分答案 推导+模版
二分答案一 定义二 算法的推导三 代码实现四 浮点数二分答案一 定义 二分答案通常用于求解在一个答案区间内的最大边界或者最小边界。主要的思想是通过判断中间点的可行性去更新左右边界直到得到最后的答案。二 算法的推导首先我们要了解几个专用的名词1.left 左边界2.right 右边界3.mid 中间点4.check(int x) check函数,用于检验可行性1.求解最大边界在求解最大的边界的过程中,我们很容易知道左右边界的更新方法,if(check(x)) l = mid; // 如原创 2021-09-16 17:31:47 · 95 阅读 · 0 评论 -
最小生成树算法
最小生成树一 prime算法1.定义2 代码实现3 prime算法的优化二 Kruskal算法1. 定义2 codefirst最小生成树first 最小生成树first最小生成树 最小生成树指的是在一个边有权的树上,求一个边权和最小的树形结构,并且使得这个树形结构要覆盖这个边上的所有点。现在求最小生成树的算法主要有两种,一个是 primeprimeprime 算法,一个是 KruskalKruskalKruskal 算法。一 prime算法1.定义 我们现在有一个集合AAA和一个集合EEE,分别为原创 2021-09-15 15:23:32 · 267 阅读 · 0 评论 -
树形dp算法
一 定义 树形dp通常指在各变元之间的关系是一个树形的结构,而非传统的线性结构,对于这种树形的dp,我们通常使用DFS去解决,时间的复杂度通常在 O(n2)O(n^2)O(n2)二 经典例题没有上司的舞会 题目的意思大概是在一个公司里面有着上下级关系,每个人都有一个快乐指数,在一个舞会里面,如果你邀请了一个人,那么他的直接下级就不能参加,基于这个状态,请问我们如何邀请可以使得快乐指数之和最大。解题思路 在点的数目较少的时候,我们可以使用 vectorvectorvector 进行存储每个点对应的原创 2021-09-14 13:58:22 · 219 阅读 · 0 评论 -
环形区间dp
dp是OI路上的一道天堑,很明显俺还在这个坑里1. 定义 这一类问题最典型的就是合并石子问题,即在一个区间上,进行元素的合并,将相邻小的元素或者区间逐渐合并成一个大的区间,最终合并为一个大的区间,在这个过程,我们需要使得一些量取得最大值,这大概就是区间dp的定义2. 例题NOI1995合并石子3. 思路1.求石子合并的最大值,转移方程如下f[i][j] = max(f[i][k]+f[k+1][j]) + sum[i][j]2.求石子合并的最小值,转移方程如下f[i][j] = min(原创 2021-09-13 18:21:06 · 332 阅读 · 0 评论 -
海伦公式判断点和三角形的关系
一 海伦公式如果有一个三角形,它的三边分别为 $a, b ,c $, 则三角形的面积为 A=s(s−a)(s−b)(s−c)A = \sqrt{s(s-a)(s-b)(s-c)}A=s(s−a)(s−b)(s−c) , s=a+b+c2s = \frac{a+b+c}{2}s=2a+b+c二 判断一点和三角形的关系三角形的三点为A,B,CA, B, CA,B,C,我们需要判断的点是DDD如果S△ABC=S△BCD+S△ABD+S△ACDS\triangle ABC = S\triangle原创 2021-09-13 12:51:52 · 545 阅读 · 0 评论 -
凸包解决数学问题
一 定义利用图像的凹凸性解决一些数学问题,如查找最大的斜率。二 例题[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rlDYjdPD-1631264643717)(/Users/chengjiajun/Library/Application Support/typora-user-images/Screen Shot 2021-09-10 at 4.27.51 PM.png)] 其实我们可以知道这道题其实就是求在长度为 [s,t][ s, t][s,t] 的子原创 2021-09-10 17:04:34 · 215 阅读 · 0 评论 -
单调栈解决取矩形问题
单调栈解决取矩形问题 前言:这一类问题不知道是什么问题,emmm大概意思就是从一个混合着可行点和不可行点的矩形中能取出的充满可行点的矩形的数目。这一类问题应该有一个官方的名字,大家如果知道可以在评论区中给出。一 思想概括对于这样的一个数据,其中1为可行点,求最多能得到多少个矩形1 0 1 01 1 1 01 1 1 1 设a[i][j]a[i][j]a[i][j]点的向上的可拓展的高度为 hhh,那么我们要查找的就是在此高度范围内包含a[i][j]a[i][j原创 2021-09-10 07:59:22 · 70 阅读 · 0 评论 -
悬线法求最大矩形
悬线法一 定义 悬线的定义,就是一条竖线,这条竖线要满足上端点在整个矩形上边界或者是一个障碍点。然后以这条悬线进行左右移动,直到移至障碍点或者是矩阵边界,进而确定这条悬线所在的极大矩阵。二 悬线法的使用 首先我们要得到一个r数组和一个l数组,记录这个点的左边可到达点和这个点的右边可到达点。在用up数组得到这个点的向上最大高度,从而得到最终的解。三 code初始化 for(int i = 1;i <= n;i++) for(int j = 1原创 2021-09-09 20:53:28 · 105 阅读 · 0 评论 -
多维dp详解
多维dp一 定义多维dp问题指的是一个问题具有多个维度,通常可类比于二维数组取数问题,进行直接暴力dp的话时间和空间的复杂度为O(n4)O(n^4)O(n4)下面以传纸条为例二 暴力的四维dp对于传纸条可以选择从上面和左边进行选择f[i][j][p][q]=max(f[i−1][j][p−1][q],f[i][j−1][p−1][q],f[i−1][j][p][q−1],f[i][j−1][p][q−1])f[i][j][p][q] = max(f[i-1][j][p-1][q],f[i][j-原创 2021-09-09 20:32:35 · 692 阅读 · 0 评论 -
Floyd 判环算法
Floyd 判环算法一 算法内容 该算法的内容类似赛跑,两个人在操场上赛跑,跑的快的一定能够比跑得慢的多跑一圈,在链表的判环中,我们可以使用一个快指针和一个慢指针,慢指针每次走一步,快指针每次走两步,当快指针和慢指针相遇的时候,就说明这个慢指针已经走了一个环二 例题Calculator Conundrum#include<iostream>#define ll long longusing namespace std;int buf[20];int next(int n,int原创 2021-08-19 19:04:13 · 56 阅读 · 0 评论 -
UVA11300 Spreading the Wealth
UVA11300 Spreading the Wealth思路 对于这道题,我们可以将其转化为一道线性代数的问题,设第iii个人的初始值为AiA_{i}Ai,第iii个人给第i−1i-1i−1个人的金币数目为xix_{i}xi,设最终值为avgavgavg,我们可以得到这样一个等式A1−x1+x2=avgA_{1}-x_{1}+x_{2}=avgA1−x1+x2=avg,设C1=A1−avgC_{1} = A_{1}-avgC1=A1−avg得到x1−x2=C1→x2=x1−C1(1)x原创 2021-08-18 15:22:45 · 125 阅读 · 0 评论 -
二维前缀和
二维前缀和 在区间查询之类的问题中我们经常用到一维的前缀和,一维的前缀和的公式较易写出sum[i] = sum[i-1] + a[i] 而对于二维的前缀和的公式较为复杂sum[i][j] += sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1]二维前缀和模版#include<iostream>#define N 5010using namespace std;int pre[N][N],n,m,x,y,z,ans;int main()原创 2021-08-11 10:20:01 · 60 阅读 · 0 评论 -
Floyd算法
一 定义 对于弗洛伊德算法而言,其本质就是对每一个作为一个中间的节点,对这个点进行松弛的操作。对每一个点进行松弛操作之后我们得到的就是我们需要的最短路二 算法核心for(int k=1;k<=n;k++) //这里的注意点:枚举中间点的循环放在最前面 for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);...原创 2021-08-06 23:22:50 · 113 阅读 · 0 评论 -
迪科斯特拉算法及其优化
算法执行步骤详解step 1 初始时我们有两个集合A,B,集合A中是所有的点,B中最开始无点step 2 向B中加入起始点,A中删除该点,并更新该点可到范围内的点的起始距离step3 随后在B中加入A中的距离起始点最小的点,并从A中删除,然后对这个数能到达的数进行一次更新,重复上面的操作直到目标的点在我们的B中本质是一种BFSvoid dijstra(int start,int end){ q.push_back(start); for(int i = 1;i <=原创 2021-07-31 08:38:53 · 454 阅读 · 0 评论 -
Tarjan算法
一 Tarjan算法简介1 定义 Targain算法本质上是一种DFS,通过对图的深度优先遍历得到图的强连通分量,在算法中我们使用一个DFN数组和一个LOW数组,DFN数组是储存这个点被搜索到的次序,而LOW数组表示的是这个点所能指向的点的最小值,如果一个图是环,那么咱们搜索完一周回溯到这个点的时候自然的会有LOW[i] = DFN[i],借助这个性质,我们再开一个栈去存储我们得到的点,不断出栈直到遇见我们最初进栈的那个起点。2 实现我们借助LOW数组和DFN数组,DFN数组存储的是每个点的DFS序原创 2021-07-19 22:45:49 · 197 阅读 · 0 评论 -
单调队列和单调栈
单调队列和单调栈一 单调队列1.定义单调队列是一种数据结构,用于存储的是在一个区间内的最大值,通常用于区间查询2 实现方式下面以存储最小值的单调队列为例,假设我们的区间范围是为n,那么在单调队列中,我们先不断的出队,去掉那些已经过时的元素,然后在让最新的元素从队尾进队,不断删除那些比它时间长并且比它还小的数3 Example假设现在用8个数要进入队列,求三个数长度的区间内的最小值进队单调队列操作333入队111干掉321 22入队51 2原创 2021-07-11 23:04:29 · 49 阅读 · 0 评论 -
最大子段和
最大子段和一 定义 最大子段和指的是在一段连续长度的区间内的最大和二 解法 使用dp的解法,f[i]=max(f[i−1]+a[i],a[i])f[i] = max(f[i-1] + a[i],a[i])f[i]=max(f[i−1]+a[i],a[i]),不断更新最大值include <iostream>#define ll long longusing namespace std;ll num[200010];ll ans[200010];int n;ll sum=-9原创 2021-07-11 21:25:07 · 96 阅读 · 0 评论 -
最大子段和
一 定义 最大子段和指的是在一段连续长度的区间内的最大和二 解法 使用dp的解法,f[i]=max(f[i−1]+a[i],a[i])f[i] = max(f[i-1] + a[i],a[i])f[i]=max(f[i−1]+a[i],a[i]),不断更新最大值include <iostream>#define ll long longusing namespace std;ll num[200010];ll ans[200010];int n;ll sum=-999999;原创 2021-07-11 13:34:38 · 1192 阅读 · 0 评论 -
30天算法突破计划——Day2
AC1Problem,求用N张邮票且只有K种的情况下可以取得的最大连续值思路使用DFS+DP的做法,在DFS中搜索每一位的取值,在DP中去搜索在这个取值的情况下能够取到的最大的最大连续数,并以此+1作为下一个数的上界,代码部分0 数据结构int ans[20]; // 是我们最终的int a[20];1 DPint dp(int t){ int f[N]; f[0] = 0; for (int i = 1; i <= a[t]*n; i++) f[i] =原创 2021-07-10 12:33:59 · 45 阅读 · 0 评论 -
差分算法基础
差分用途 差分主要用于区间的修改,可以实现在一个区间内的数字的增减,和线段树相比具有代码量少,速度快的优点。 - -|线段树也太难了吧实现原理 首先我们需要一个差分数组,在差分数组内保存的是这个数和前一个数的差值。所以只要修改一个数,那么他后面的数就会全部得到相同的修改。在这一性质下,如果我们要对区间[a,b][a, b][a,b]内的数全部加上ccc,那么只需将f[a]+b,f[b+1]−cf[a]+b, f[b+1]-cf[a]+b,f[b+1]−c.The Example样板题solut原创 2021-07-10 11:23:08 · 228 阅读 · 0 评论 -
30天算法突破计划——Day2
30天算法突破计划——Day2Day1AC1Problem,求用N张邮票且只有K种的情况下可以取得的最大连续值思路使用DFS+DP的做法,在DFS中搜索每一位的取值,在DP中去搜索在这个取值的情况下能够取到的最大的最大连续数,并以此+1作为下一个数的上界,代码部分0 数据结构int ans[20]; // 是我们最终的int a[20];1 DPint dp(int t){ int f[N]; f[0] = 0; for (int i = 1; i <原创 2021-07-09 14:39:56 · 57 阅读 · 0 评论 -
三十天算法突破计划 Day 1
三十天算法突破计划 Day 1AC1Problem,已知二叉树的前序遍历和后序遍历,求这个树的中序遍历的可能数目思路 首先说明两条性质一 在前序遍历中,若一个节点只有一个子节点,那么它一定在它的子节点的前面二 在后序遍历中,若一个节点只有一个子节点,那么它一定在它的子节点的后面 对于一个树的前序遍历和后序遍历,我们考虑一个最小的单元,就是两个节点的树,在这个树里面,不管第二个节点是在左边还是在右边,都能得到一样的前序遍历结果和后序遍历的结果,所以在这个里面我们要找的就是只有一个支的节点原创 2021-07-08 20:06:32 · 69 阅读 · 0 评论 -
DFS和BFS的递归及非递归实现
DFS和BFS的递归及非递归实现一 DFS1 递归实现 定义一个搜索的函数,对附近八个方向的点进行搜索,如果这些点可以满足条件,那么对这些点进行继续搜索。void DFS(int x,int y){ if(x<1||x>m||y<1||y>n) return; // 如果超过范围,直接返回 if(filed[x][y]) filed[x][y] = 0; // 如果那点有石油那么继续搜索 else return; for (原创 2021-05-06 14:36:49 · 1334 阅读 · 0 评论 -
欧拉筛法
欧拉筛法用途 用于查找在一定范围内的所有素数原理 在一定的范围内,如果一个数不为质数,那么它一定可以被表示为一个数和另一个质数的乘积,我们可以借此在一定范围内筛选掉不为质数的数,最后剩下的都为质数。代码#include<iostream>using namespace std;#define MAXN 100000010#define ll long longll prime[MAXN];bool vis[MAXN];int cnt=0;void Euler_prime原创 2021-04-23 20:33:30 · 395 阅读 · 0 评论 -
KMP算法
KMP算法用途kmp算法通常用于匹配字符串中的目标字符串暴力做法思路 暴力做法思路很简单,假设被搜索字符串为a,目标字符串为b,用i表示a中当前进行比较的字符的位置,用j表示当前进行比较的字符的位置。代码int violent(string a,string b){ int i = 0; int j = 0; for(i = 0; i <= a.length()-b.length(); i++) { int can = 1;原创 2021-04-22 12:13:30 · 164 阅读 · 1 评论 -
博弈算法
一 巴什博弈1 定义 假设这里有一堆数量为n的石子,有两个人从石堆里吗取出1~m颗石子,最终没有石子可取的那个人输。2 输赢情况情况一:n=m+1先手取s(1~m)个,后者再取n−s个,先者必输 \quad n=m+1 \\ 先手取s(1~m)个,后者再取n-s个,先者必输\\ n=m+1先手取s(1~m)个,后者再取n−s个,先者必输情况二:n=(m+1)∗r先手每次取s(1 m)个,后手每次取n−s个,最终还是后手必赢 \quad n=(m+1)*r\\ 先手原创 2021-04-03 23:21:24 · 302 阅读 · 0 评论 -
搜索算法——DFS和BFS
DFS和BFS搜素算法一 DFS(深度优先搜索)原创 2021-04-01 10:25:13 · 158 阅读 · 0 评论 -
并查集的两种实现方式
先来看一道题目 假设现在有n个人,我们将其编号为1-n,在他们之间一些人有另外一个人作为上司,原创 2021-03-29 23:32:20 · 501 阅读 · 0 评论