自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(39)
  • 收藏
  • 关注

原创 各种莫队算法

莫队算法,是一种以分块为基础的维护区间[1,n]的离线算法,主打一个优雅的暴力应用场景:对于q个询问,每次询问区间[l,r]算法核心:我们将区间[1,n]按每块长度为进行分块,则block[i]表示下标为i的元素所在的块的编号。我们对q个询问以block[l]作为第一关键字,r作为第二关键字由小到大排序,然后再逐一处理询问。

2024-09-30 22:11:19 1036

原创 上下界网络流

我们知道,仅有上界的网络流,可以通过bfs寻找增广路进行扩流从而找到最大流。但如果给每条边的流量加一个下界,我们应该怎么办呢?设边w的流量上界为sup,下界为inf一个思路是先把每条边下界需要流的inf流量流满,然后再给出sup-inf的边,代表可流可不流,这样,就可以在保证取到流量下界的同时不超出流量上界。那么我们具体该怎么实现呢?

2024-09-30 21:24:26 697

原创 网络流最大流,费用流

网络流,指的是在一个每条边都有容量的有向图分配流,使得一条边的流量不会超过他的容量有向图称为网络,顶点称为结点,边称为弧源点:只出不进的顶点汇点:只进不出的顶点容量和流量:每条有向边上有两个两,容量和流量。

2024-09-08 11:21:11 870

原创 轮廓线dp、插头dp

轮廓线:对于一个n*m棋盘上的决策,当我们考虑到(i,j)这个格子时,第i行前j-1个格子的下边以及第j个格子的左边以及第j到第m-1-j个格子的上边所组成的一条线,我们称之为轮廓线轮廓线dp:当我们在棋盘第(i,j)格子上放置棋子时,我们的决策受到且仅受到(i,j)格子左边以及上边的状态的影响,我们这个时候就可以 采取轮廓线dp的方法来解决题目大意:给出n*m的棋盘,其中为1的格子必须铺线,为0的格子禁止铺线,棋盘上可形成多条回路,求所有合法方案数。

2024-09-08 10:19:43 761

原创 R数据科学练习题部分解答,持续更新

本文章作为《R数据科学》书籍练习题解答合集使用。推荐搭配Ctrl + F搜索使用。

2024-08-28 18:34:42 793

原创 树上dp之换根dp

换根dp是树上dp的一种我们在什么时候需要用到换根dp呢?当题目询问的属性,是需要当前结点为根时的属性,这个时候,我们就要使用换根dp换根dp的基本思路:假设题目询问的的属性为x通常我们会进行两次dfs第一次dfs,我们选取任意一个结点作为给出的无根树的根,对其进行dfs,并求出这个根的x,以及一些其他辅助数组(即节点与其子树的一些属性关系)第二次dfs,我们记dp[i]为对于结点i而言,节点i作为树的根时,我们要求的属性x。

2024-08-13 22:46:07 1025

原创 状态压缩动态规划——状压dp

状压dp:意思是将状态进行压缩,从而更容易地写出状态转移方程通常做法:将每个状态(一个集合)用二进制表示,每个位的1就代表着这个编号的元素存在,0就代表着这个编号的元素不存在,如二进制100110,即是集合{1,2,5}的压缩通过状态压缩,我们可以使得状态通过位运算来判断是否可以转移。

2024-08-09 22:33:33 787

原创 Dplyr With Data Transition

8/1变量有以下几种类型:下面重点介绍以下五个函数:格式:(下文中表示表达式),例如筛选出所有1月1日的航班:如需同时输出结果,则可以添加一个括号:数据集赋值操作类似。附:如果想要确定一个值是否为缺失值,可以使用函数:Arrange()格式;,其中x表示列名。如果列名不止一个,那么久使用后面的列在前面排序的基础上继续排序:需要注意的是该操作会修改数据集。使用可以按列进行降序排列:缺失值总是排在最后:这可能比较费解,因为常识上缺失值应该对应无穷小,因此对于这一悖论需要额外注意。倘若需要将缺

2024-08-04 01:27:08 880

原创 SA后缀数组

子串:在一个字符串s中,取任意i

2024-08-01 18:10:52 521

原创 可持久化线段树/平衡树

对于一棵树来说,我们每次单点修改的时候,无非就是修改了它的左子树或者是右子树,那么对于新的版本来说,当他修改的是左子树的节点的时候,显然我们可以继续沿用历史版本的右子树,也就是只要复制并修改一棵左子树就可以了;这就是可持久化的核心思想。操作和可持久化线段树类似,我这里采用的是FHQ-Treap实现的平衡树,在split的过程中会修改树的值,因此在split的时候需要开新点,由于merge的时候连接的都是split开的新点,所以merge就不用再开新点了。

2024-07-03 12:33:20 563

原创 树上差分的公式推导

其实这两者在这个节点这里是等效的,所以我们随机减免一个就可以了,我们这里选择给dep[x]的权值减1。我们再来分析lca到y的路径上的结点j,对于这个结点j,如果x出发的人能够被他观测到,那么应该满足关系式:dep[x]-dep[lca]+dep[j]-dep[lca]=w[j],这样一来,我们就可以得到:dep[j]-w[i]=2*dep[lca]-dep[x],也就是说,对于路径上的每个这样的结点j,我们只需要计数2*dep[lca]-dep[x]的个数,就可以知道他可以观测到多少个人了。

2024-07-03 01:46:52 327

原创 树状数组——点修区查与区修点查

树状数组是一种代码量小,维护区间的数据结构他可以实现:1.区间修改,单点查询2.单点修改,区间查询当然,二者不可兼得,大人全都要的话,请选择线段树。

2024-07-01 01:18:45 211

原创 动态DP&动态树分治

这是一条子节点向父结点转移的方程,因此,我们只需要对树的根节点进行dfs,先更新子节点的值,再用其来更新父节点的值,最终就可以得到根的两个dp值,f[root][0]和f[root][1],我们只需要取两者中的较大者,就是该棵树的最大权独立集。我们可以想象一下,我们现在对结点u进行了点权修改,显然u的子树的dp值是不需要修改的,u的兄弟结点的dp值也是不需要修改的,我们需要修改的只有u节点到根结点这一整条路径上的结点的dp值。其中f[x][0]表示不选择节点x加入点集,以x为根的这棵树的最大点权和。

2024-06-30 22:25:36 1394

原创 LCT——Link Cut Tree及其应用

我们知道,想要维护树上的一段区间,我们可以采用重链剖分来将其划分但是,树链剖分只能够维护静态(树的形态不发生变化)的树,倘若我们需要动态对树的形态进行修改,比如将某个结点换为树的根、树中边的增删、子树合并和分离操作等,并需要在线地回答相关询问,那么每一次修改后,轻重链都需要重构,效率就会大大降低所以,我们需要一种数据结构能够动态地维护树上的区间这就是今天要用到的LCTLCT是在1982年由Tarjan大佬等人提出的。

2024-06-30 01:06:50 671

原创 离散化,矩阵快速幂,广义矩阵乘法

对于一个线性的递推式,我们可以将其写成1行n列的矩阵形式,并找到一个矩阵A,使得矩阵[矩阵之间的乘法具有结合性,因此,我们可以采用普通快速幂的思想,对矩阵进行快速幂运算。在这种情况下,我们将opt1和opt2相应地将矩阵乘法中的乘法和加法操作替换掉。那么,对于一个数列1,50,666,8558555,9989898989而言。就得到了广义矩阵乘法,其满足矩阵的结合律,可以使用快速幂。那么这个1,2,3,4,5就是上述原数组离散化后的id。其实我们可以把他们看作1,2,3,4,5。

2024-06-28 23:00:02 755

原创 树链剖分及其应用

1.重儿子:假设节点u有n个子结点,其中以v子节点的为根子树的大小最大,那么v就是u的重儿子。只需要让top[u]的深度较大的一方跳到其top[u]的父亲结点上,自然就到了另一条新链了。首先,我们可以很简单地通过dfs获取一个结点的dep,fa和siz,从而也就获得了siz。假设他们在同一条链上,也就是top相同,那么他们的lca就是深度比较小的一方。siz[u]:以u节点为根的子树的大小。重儿子的top就等于自己u节点的top。top[u]:u结点所在的链的顶点。4.重边:结点u与重儿子连接的边。

2024-06-27 00:50:07 448

原创 差分数组与树上差分

假设我们现在需要维护一段区间,实现对一段区间[L,R]的数的加/减,以及对区间中某个数的查询最简单的方法把这段区间的数都记录到数组a[N]中,每次修改都对区间[L,R]的每一个数进行加减操作,然后在查询第k个数的时候返回a[k]在上述算法中,修改操作的复杂度是o(n),而查询操作的复杂度是o(1)这种操作在查询次数大,修改次数小的时候很高效但在修改次数大,查询次数少的时候,就显得很慢了那么在这个时候,我们可以使用差分数组来维护这段区间。

2024-06-26 21:06:14 461

原创 动态开点线段树,线段树合并

而动态开点线段树,就是对于给定的区间[L,R],我一开始是一棵空的线段树,或者说有一个节点(L到R),当我需要插入某个下标为k的数的时候,我再一路创建所表示区间包含k的结点并修改(如果这个结点先前没有被创建的话),从而节省了大量的内存。当我们递归到一个结点,如果x或y在这里没有结点,那么直接搬用对方的结点过来即可(如果双方在这里都没有结点,那么这里就仍然为空节点了)对于传统线段树,我们都是把区间开满,然后要修改哪个区间,就去找包含那个区间的结点。当我们递归到叶子结点的时候,合并权值。也就是需要合并线段树。

2024-06-26 20:36:44 292

原创 倍增法找lca——最近公共祖先

在这种情况下,我们只需要x和y同步往上爬,直到他们两个的祖先重合,就可以得到x与y的公共祖先了。这个时候,我们就应当先找到一个x的祖先,这个祖先和y的深度相同,然后再按照情况2处理。这和把一个十进制的数转为一个二进制的数是一样的,我们都是从最高位往最低位填1。所以想要实现这样的算法,我们需要记录各个点的深度,以及他们。2.dep[x]<dep[y]或dep[y]<dep[x]一个最简单的办法就是沿着x和y的父节点一个一个往上找。对于结点x和y,需要找他们的最近公共祖先。这个时候,x与y的lca一定是y。

2024-06-26 20:02:56 416

原创 FHQ_Treap笔记

【代码】FHQ_Treap笔记。

2024-06-23 16:57:55 269

原创 splay树——伸展树

【代码】splay树——伸展树。

2024-06-23 00:49:38 386

原创 tarjan算法——割点、桥,强连通分量、缩点

在一张无向连通图中,若将结点u去除后,该图不再连通,则称结点u为割点。

2024-06-14 17:52:31 1015

原创 差分约束系统

现有给出若干个形如的不等式约束,其中求是否存在一组关于到的解。

2024-06-14 12:14:02 857

原创 线段树:区间修改——加、乘,区间查询

【代码】线段树:区间修改——加、乘,区间查询。

2024-06-12 13:09:58 365

原创 图论常见算法总结——prim,kruskal,dijkstra,floyed,bellman-ford,spfa

我们对到达结点u的最短路径所经历过的结点数cnt进行统计,显然cnt[u]不会超过n,若超过了n,说明已形成环路,且一定是负环。我们先建立一层外层循环,在每一次循环中,都枚举图中的m条边,并对起点到每一个结点的最短路径进行松弛更新,可以保证,每次最少更新一条边,那么在至多n-1次循环后,在循环中将不会再有边更新。任意选取一个起点u,设已加入树的结点为V,总结点为T,则每次搜索连接V与T-V的最短边,并使之加入V(即从T-V向V中加入一个新的节点),当T中所有节点访问完成,即为最小生成树。

2024-06-11 11:52:14 1179

原创 c++实现扫雷

明明是用c++写的,却一股c的味道。闲得无聊于是写了一个扫雷。

2024-06-07 15:43:39 184 1

原创 string类模拟

【代码】string类模拟。

2024-06-01 15:09:40 230

原创 C++ 类的学习笔记

【代码】C++ 类的学习笔记。

2024-05-27 11:26:06 319

原创 动态规划——所有可能的真二叉树

最近正在学习动态规划,今天就在力扣上遇到了相应的题目。递归方法——记忆化递归——动态规划。然后通过记忆储存避免递归的重复运算。最后把它写成动态规划的形式。

2024-04-02 16:04:41 490 1

原创 数据结构——队列、最大堆、优先级队列

队列是一种只允许在一端进行插入操作,而在另一端进行删除操作的线性表。队列,顾名思义,就好像我们在超市结账排队一样,先排进队的人先买单,先进入队列里的元素先出队,也就是 先进先出的特点(First In First Out,FIFO),允许插入元素的一端称为队尾,允许删除元素的一端称为队首。

2024-04-01 13:18:01 1685

原创 数据结构——树、二叉树、二叉搜索树

树结构是一种数据结构。它由结点以及连接结点的边构成,如图所示:其中圆点表示结点,实线表示连接结点的边黑色的结点我们称为根,是一棵树的起始点,如果一棵树有根,我们称之为“有根树”树有以下几个概念:父结点、子结点、兄弟结点:如图中的结点1、2、3,它们具有共同的父结点,也就是结点0;而结点6、7、8,它们的父结点是结点2.相应地,我们也说结点6、7、8是结点2的子结点,而结点6、7、8相互称为兄弟节点(具有相同的父节点)叶结点:没有子结点的结点,如结点4,结点11内部结点:除叶结点以外的结点。

2024-03-31 23:51:45 625 1

原创 数据结构——栈、括号问题及其变式

栈是一种数据结构,其按照最后进入栈的数据最先出栈的规则管理数据(Last In First Out,LIFO)其中栈中最后一个元素的下一个位置称为栈顶,相应地也存在栈底,当栈顶到达预先开好的栈的空间的时候,称为栈满;当栈内没有任何元素的时候,称为栈空一开始我们可能不理解,这样的奇怪的数据结构特点有什么作用呢?没关系,我们就先记住,后面在使用栈的时候自然就明白了。

2024-03-30 00:31:46 681 2

原创 利用归并排序的局部有序性——计算逆序数

我们来看这样一道题目:给出逆序数的定义:在数列A={}中,如果有一组数(i,j)满足,且i

2024-03-29 00:29:45 433 3

原创 高等排序——分割与快速排序

快速排序在分割的过程中会交换不相邻的元素,因此属于不稳定的排序算法快速排序的效率与key值的选取息息相关,如果在分割时能恰好选到中间值,则整个过程与归并排序一样,大致分为层,平均时间复杂度为O(nlogn),是一般情况下最高效的排序算法。若像我的上述代码(前后指针法)一样,采用固定的方式选取key值,那么当处理某些顺序的数据(如已经排序完毕的数组)的时候,效率会大打折扣,最坏的情况,时间复杂度甚至高达O(),甚至有可能导致递归的深度过大而栈溢出。

2024-03-28 22:27:47 1725 1

原创 高等排序——归并排序

前面学习了初等排序,其时间复杂度一般为O(),当面对庞大的输入数据时,这种排序效率就显得十分低下,在这里,我们运用递归与分治的思想,可以实现更加高效的排序算法今天我学习的是归并排序。

2024-03-28 00:25:17 167 1

原创 初等排序——插入排序、冒泡排序、希尔排序

对于一个给定包含n个元素的数组,我们总需要将其按照相对大小进行排序,进而方便进行数据处理。如排序学生的成绩,员工的薪水。这就设计到了排序算法今天我学习的是三种初等排序方法——插入排序、冒泡排序、希尔排序对于不同的排序算法,我们有几个重要的关注点:1.时间复杂度:是数组元素n的函数,越低效率越高2.排序的稳定性:当数据中存在2个或2个以上的数值相等的元素时,这些元素在排序处理前后的顺序不变,被称为排序的稳定性。

2024-03-26 22:56:19 714

原创 数值算法——快速幂

在上一篇素性检验中,我们运用了库函数pow来求得的值,这是非常方便快速的。如果不使用pow,我们如何编写一个函数来求得一个数的整数次幂呢?

2024-03-26 10:38:56 330

原创 数值算法——查找素因子,查找素数,素数检验

素数,是大于1的自然数,其唯一的因子是1及其本身。相对的,合数是大于1的非素数的自然数。素数的作用:由于很难将两个素数的乘积重新分解为因子,因此,某些类型的密码可以使用两个大素数的乘积来提供安全性。因此,下面将学习关于素数的一系列算法。

2024-03-26 08:59:08 1893

原创 数值算法——最大公约数

对于数a,b,假定a>b,我们遍历i=1到i=b,并保存a%i==0&&b%i==0的i的最大值,此为GCD(a,b)。为了准备五月初转专业的程序设计考试,一开始在力扣上刷了很多的题目,发现里面的算法难度较高,我学习的效率较低,于是决定开始系统地学习算法基础。在这里,由公式的性质,我们无需判断a与b的大小关系(假设a<b,则a%b的值等于a,a与b自动交换了位置)很显然,这个公式具有迭代的性质,我们可以运用循环语句算出GCD(a,b)该法的关键在于运用了数学公式——GCD(a,b)=GCD(b,a%b)

2024-03-25 23:30:26 311

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除