自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 可持久化01Trie

假设max_id是3,限制条件是2,表示的是这个字数有一个数它的下标是3,所以就可以遍历这个节点,反之,就不可以遍历,因为每一个节点它的下标大于限制条件,都是l前面的数,所以就不能遍历。这里我们都是动态开点,也就是假设当前我们的数是1,所以我们要向下遍历找到一个0,由于我们是有限制条件的,所以对于每一个节点,加入他的0的这个儿子的max_id大于我们的限制条件,也就是这个子树里面存在一个s{i],它的下标大于或等于我们的限制条件,所以我们就可以往0这个方向走。下面就用上面这个例题来介绍它的用处!

2023-11-09 21:10:26 183

原创 高精度计算

一个非常的大的数除以一个较小的数,计算商和余数。可能两个数有个为0,所以要特别判断一下。两个非常大的数相减,可能为负数。一个非常大的数乘以一个很小的数。不需要判断大数是否为0。两个非常大的数相加.

2023-10-15 21:32:53 144

原创 分解质因数

将一个数质因数分解,输出每个质因数和它的指数。

2023-10-09 21:41:17 71

原创 求质数(欧拉筛)

欧拉筛为求质数最快的方法,O(n)的复杂度,每个数只会被筛一次。

2023-10-09 17:02:36 85

原创 进制转换

这里可能将十进制转化为14或1进制,所以10用A,11用B表示,依次类推。将其他进制下的数转化为10进制下的数,通常采用秦九韶算法。1.十进制转化为其他进制。

2023-10-07 17:04:42 203

原创 快速幂

假设要求a得k次方模p的结果,只需要求出a的0次方,a的1次方,...,a的logk次方这些就可以了,将复杂度o(k)转化为o(log k)。每次对于k的最后一位看看是不是1,是1就乘上a(这里a是没k的右移而变化)。这里刚开始是第0位,所以乘上a,如果是第1位,就需要乘上a^2,第2位就需要乘上a^4,所以每次都a乘以a更新a就可以了。这里如果暴力做的话,每次都会遍历k次,也就是2*10^9,一共有100000次,显然会超时,所以就需要采用快速幂来求解。

2023-10-02 20:28:24 145

原创 约数相关问题

最后的约数之和应该是(p1^0+p1^1+...+p1^k1) * (p2^0+p2^1+...+p2^k2) * ... * (pn^0+pn^1+...+pn^kn)。为什么是这样呢,因为所有从这些括号里选择一个数,这些数相乘也就构成了某个约数,所有这些数相加也就是最后的约数之和!所有这些指数k1,k2..,kn的不同选法也就构成了不同的约数,全选是最大的,与就是本身,都不选,也就是1.所以有(k1+1)*(k2+1)*..*(kn+1)种选法,也就是有这些种约数。

2023-10-02 12:50:56 91

原创 最短编辑距离

特别注意一下,这里首先要初始化一下最开始的边界情况,因为这里从1开始遍历,那么f[0][3]如果不特别初始化一下的话,就是0,那么显然是错误的,所以提前初始化一下。如果要在第i个位置后面增加一个元素可以和b的匹配的话,那么f[i][j]=f[i][j-1]+1。这里有两种情况,第一种情况a[i]==b[j],那么f[i][j]=f[i-1][j-1]。第二种情况,a[i]!=b[j],那么f[i][j]=f[i-1][j-1]+1。如果要删除第i个位置的元素的话,f[i][j]=f[i-1][j]+1。

2023-09-29 20:23:12 198

原创 STL upper_bound和lower_bound函数

这里有三个参数,第一个参数是要查找的第一个元素的位置,第二个参数是要查找的最后一个元素的下一位,第三个参数是x(表示找到第一个大于x的位置)。最后还要减去一下数组的其实位置,最后返回的就是一个数字(也就是下标)。这里的两个函数所运用的对象必须是非递减的序列(也就是数组,数组必须是非递减的),只有这样才可以使用upper_bound和lower_bound这两个函数。和上面一样,找的是第一个大于或等于x的位置,减去首地址,返回的就是下标。首先包含头文件#include

2023-09-29 14:20:29 220

原创 判定二分图(染色法)

2.已经有颜色了,然后判断一下当前这个点和他所能扩展到的点是不是相同的颜色,如果相同就返回false(这里的搜索只要有一个不符合要求直接返回false)。注意一下这里要遍历每个点然后进行dfs,如果从第一个点dfs的话,这个图可能不是一个。1.这个点没有被染色,那么就去染它。

2023-09-26 21:25:18 77

原创 求最小生成树(kruskal)

2.逐次遍历每条边,如果当前边的两个点不在一个集合,那就把他们两个加到一个集合里面(加的过程中边数要加,权重也要加)。kruskal算法最慢的就是那个排序的过程,其他的是非常快的。算法流程非常的简单,因为有并查集的路径压缩。这里为什么就是最小生成树呢?因为我们遍历到的边都是最小的,所以总体就是最小的。3.最后判断边数是否为n-1。(如果不是也就是图不是联通的)1.对所有的边从小到大排序。

2023-09-26 20:27:54 72

原创 求二分图的最大匹配(匈牙利算法)

妥协的过程就一直递归。那么匈牙利算法为什么可以找到最大匹配呢,因为我们每次遍历到新的点,都假定它的优先级最高,其他点都必须向他妥协,那么如果其他点可以妥协,就让新的点(霸道总裁)连接这个可以连的点,那不就是比原来的图又多了一条边吗,这样不就会一直增加吗,所以可以找到最大匹配。那就接着遍历他所能连接的第二个点(一直到他所能连接的第n个点),再继续最开始的过程,如果遍历刀到第k个点刚好可以让其他点妥协,那么就成功了。那么就让当前这个点连接他所能连接到的第一个点,另外一个放弃这个点,妥协然后和另外的点连接。

2023-09-26 20:15:14 60

原创 图的宽度优先遍历

【代码】图论的遍历。

2023-09-24 23:20:00 100

原创 图的深度优先遍历

【代码】图的深度优先遍历。

2023-09-24 23:16:44 40

原创 求最短路(Dijkstra算法)

首先,这里的数据范围比较大,所以使用邻接表来存储。然后这里heap存的pair类型的数据,注意这里的first和second不要交换,first存的是距离,因为要对距离排序。最后就是dijkstra算法的本质了,每次在被更新的点中取一个距离最小的点(这个点的要在!st集合中),每次更新一次,就将这个点加入st集合当中。最重要的是找到一个没有被确定最短路的距离起点最短的点。首先dijkstra算法的最重要的一点是每次找到被更新的距离的所有点中的一个距离最小的点,然后去更新一下他能到达的点的距离。

2023-09-24 23:13:45 52

原创 哈希和字符串哈希

字符串哈希的话,首先应该吧字符串哈希成一个数字,这里应该哈希成一个p进制数,但是p取什么最不容易产生冲突呢?经过权威验证,p=131是最好的,所以只要是算法题,直接p取131就是最好的。但是呢N=2^64最好,这个可以不用取模,直接设置成unsigned long long就可以,因为溢出的话编译器自动进行取模。计算一个区间的哈希值使用前缀和,然后比较一下两个区间的哈希值就可判断字符串是否相等。这里使用拉链法来进行存储,也就是链表的操作,但是首先要初始化一下h数组元素值全为-1。

2023-09-18 19:43:57 40

原创 堆和堆排序

用数组模拟小根堆,主要就是up和down函数。

2023-09-17 14:54:44 37

原创 并查集

因为我们是先把a的祖先改为b的祖先,那么此时计算数量的话,c[b的祖先]+=c[a的祖先]//因为有上一句,所以这里相当于c[b的祖先]+=c[b的祖先],那么显然是错的。所以这里计算数量的时候,要先加,然后在更新。

2023-09-16 12:29:49 38

原创 trie数--最大异或对

我想了半天,我刚开始以为每一位的影响力是一样的,所以贪心是错误的。但是呢,这里我们是从最高位开始枚举的,所以我们要每次局部最优就可以了,如果存在两个选择,我们就选那个不一样的,因为如果我们选一样的话,那么就小于那个不一样的,因为越高位它的影响力是越大的。所以用trie树存储一下每个数(一个数也就是一个树)就可以了。最后遍历一下每个数,res取一个max就可以了。注意,这里我们有31位,所以最大就是31*N(N个数)。如果2^0+2^1+......+2^32会很大,所以M=31*N。

2023-09-15 22:30:05 39

原创 KMP算法

这里在进行匹配的时候,j表示的含义是对于每个i而言已经匹配了j个字符,然后这里判断j+1和i是是不是匹配的,如果不匹配j=ne[j],这里的ne[i]表示的是p[i]包含i前面最大的前后缀的长度,所以就可以直接移动了。求ne数组的话,如果不好理解,就可以先写KMP匹配过程,然后再写next数组构造过程,就相当于把s写成p,然后在更新每个ne[i]的值。刚开始的话,ne[1]=0,因为只有一个字符的话,最大的前后缀长度为0,因为不可以超过i本身,否则移动跟没移动一样。

2023-09-15 17:04:46 43

原创 单调队列

这里的话,单调队列里面的元素始终是单调的,并且前面的元素比后面的元素先遍历到,所以要判断元素是否不在窗口内了,只需每次判断对头是否在窗口内就行了,这个必须在最前面判断。

2023-09-14 22:23:06 31

原创 静态双链表

双链表的话,这里不定义指针,而是定义左右两个节点。l[ ]和r[ ]数组的意思是:l[k]表示的意思是k左边的节点,存的值是左节点的地址,r[ ]也一样。还有也要注意一下add操作,倒数第二个和倒数第三个不要写反。刚开始要初始化一下。这里就不需要add_to_head函数了,因为我们有左节点。

2023-09-14 13:51:08 70

原创 静态单链表

这里要初始化,head=-1;注意这里头指针就是静态链表的第一个元素,而不是head头指针。因为我们插入一个元素,idx++。所以第k个插入的元素就是e[k-1],

2023-09-14 12:08:48 28

原创 离散化

这里如果按照朴素算法的话,就需要2e9的空间来存储,其中用到的区间只有n+2m个数,所以很多数是完全用不到的。举个例子:-900,0,12321,21332143214这四个位置上+c,其中这么多数的话都是0,没有任何意义,所以我们采用离散化。直接映射成1,2,3,4.用find函数,注意这里二分返回的话加一,因为要用前缀和。注意这里进行数组去重。

2023-09-13 22:46:17 28

原创 二维差分矩阵

这里构造差分矩阵其实就是在全部都是0的b矩阵中插入a[i][j],这样就可以构造出差分矩阵,注意insert函数的写法,这样在差分矩阵中,可以将左上角为x1,y1,右下角x2,y2的矩阵中每个元素加个c。这里构造差分矩阵就把把每个点想象成一个矩阵,比如只插入一个a[2][3]时,将刚开始全0的b数组,每个元素的加或减,这样求b数组的前缀和的时候,只有a[2][3]为数,其余都是0.以此类推,可以a数组的每个元素插入到b数组中,这样b数组的前缀和就是a数组,可以得到整个差分矩阵。

2023-09-12 20:18:22 42

原创 P4124 手机号码

这里最难的是定义状态。f[pos][v][u][state][k4][k8]表示后pos位,当前位的前一位是v,前前位是u,是否有三个相邻的数字,是否有4,是否有8。比如:324wqer和724werwe 这两位数字的前三位是相同的,也就是可以记忆化搜索。这类题目都可以使用模板,就是状态的表示要合理。

2023-09-09 17:30:00 43

原创 p2657 windy数

这里dfs的参数要存一下当前位的前一位的值,即last,因为刚开始0也是windy数,所以last的初始值应该为-2。最后套一下模板就可以了。

2023-09-08 17:14:21 50

原创 p2602 数字计数

这里从大到小枚举位数,可以将O(n*n)的复杂度降为个位数乘以个位数的级别,非常优秀。从大到小枚举位数,假设这里枚举到了abcdefg七位数,先计算后面六位数每个数字出现的次数,然后计算0到a-1的数字的在第七位次数,最后计算后面六位数的大小,再加个一就是当前位的数字的次数。因为当前位置是0的数字我们计算了一下,也就是前导0,0bcdefg这个数字不符合要求,所以应该剪掉。最后利用前缀和的思想输出最终的答案。这里的记忆化搜索代码可以当作模板使用来解决计数DP类型的题目。

2023-09-08 13:15:30 41

原创 最长上升子序列

我么可以使用STL的lower_bound函数在f数组里面找到第一个大于或等于它的位置,因为它是大于或等于当前遍历到的这个数,所以我们就要去替换它,因为f数组的定义是长度为i的上升序列的一个最小的结尾,我们用lower_bound找到这个位置,因为这个数一定加在比他小并且是最长的一个序列的后面,注意一定是最长的一个序列,那么我么这里的f数组刚刚证明了是严格单调递增的。因为这里的f[6]是根据f[5]来的,有一点动态规划的思想,所以它的一个最小结尾是根据大于长度是5的一个最小结尾的所有数的一个最小值。

2023-09-05 23:56:43 44 1

原创 分组背包问题

这里和01背包问题有点不同,就是一个组里面最多只能选一个物品。f[i][j]表示前i组物品背包体积为j所能获得的最大价值。那么这里的状态转移,首先可以第i组物品一个都不选,也就是f[i-1][j]。然后就是第i组物品中选一个,和01背包问题一样,取一个max就可以了。也可以进行滚动数组进行优化。

2023-09-05 20:58:43 46 1

原创 多重背包问题

为什么呢,因为2000*1000*2000>1e8,所以就会tle。那么就要按照AC代码进行二进制优化,优化完就是2000*log(2000)*1000=2000*1000*11<1e8。显然时间符合了,再进行滚动数组优化,就可以AC了。不进行滚动的话,12010*2000*4>64000000。这里我们的物品的数量是2000*1000,那么空间复杂度2000*1000*2000*4显然大于64000000。但是这里我们不能把一个物品有多少份,而去给它分成多少份,这样的话,会mle。

2023-09-04 21:49:13 40 1

原创 完全背包问题

这里的话,可以用滚动数组优化,读者可以自己优化。和01背包差不多,状态的转移就有略微的差别,也就是选了第i个物品之后不是从前i-1个物品中选了,而是还是从前i个物品中选,还是很好理解的。

2023-09-04 20:35:16 46 1

原创 01背包问题

如果选,那么f[i][j]=f[i-1][j-v[i]]+w[i],这里的意思是如果你选了第i个物品,那么它所获得的最大价值就相当于你在前i-1个物品中选,体积变为j-v[i]所获得的最大价值加上你选择第i个物品的价值w[i]。那么如果你没选呢,就相当于你从前i-1个物品中选,背包体积为j的所获得的最大价值。从AC代码中我们可以注意到,f[i][j]只会和f[i-1][]相关,也就是第i层只会和第i-1层相关,前面的i-2层是无关的,所以我们没有必要开f[N][N],只需要开f[2][n]就可以了。

2023-09-04 20:29:16 42 1

原创 BFS 例题

首先这里还是和我上一篇博客的题目一样,因为这里a和a必有一个是大于0的,所以这里要首先判断它的起点是不是最安全的,但是这里题目好像没有这个测试数据,也就是写不写都一样。然后这里的几个if语句要写正确(因为没写不能走她走过的路,就因为这我调试了一个多小时),所以代码不能马虎,这里的话,直接在while语句中就可以判断是否能找到。值得注意的是,这里的memset的格式初始化无穷大,因为一般测试数据都是小于1e9的,所以写0x3f就可以满足要求了,它如果要加上数的话,也不会溢出,较0x7f是有优势的。

2023-08-21 18:52:46 41 1

原创 BFS 例题

这题为BFS入门题,这题值得注意的是,如果你将return mp[m][n];那么它将不会通过,因为a和b两者其中一个一定要大于1,所以终点是1,1的话,他在输出错误答案。所以正确的做法应该是将return语句放到while循环外面。这相当于模板代码,最好这样写,不然很容易出错。

2023-08-21 09:06:59 60 1

原创 DFS 例题

n=7,k=4,这里已经搜到了第三位,1,3,_,_。这里的话第三位必定是大于或等于3的,所以后面最小的组合是1,3,3,3.此时就已经是大于7了,按照我们常规思路的代码这种情况sum=4<7,所以没有剪枝掉,所以我们要进行进一步的剪枝。这里是一般的思路,那么这个代码是没问题的,但是他的时间复杂度太大了,会t两个点,所以我们要进行剪枝,这里if(sum>n)return;sum+(k-x+1)*i>=n //4+(4-3+1)*3和 7进行比较,显然前者更大,所以这种情况直接剪枝。

2023-08-20 17:18:06 37 1

原创 DFS 例题

这里值得注意的是:这题是不需要恢复现场的。因为这里要记录走过的最大的瓷砖数,也就是瓷砖可以重复走,但是不能重复计数。如果恢复现场的话,那么在某一点又走到了之前的位置,并且进行了dfs,那么就要计数了。那么你之前走过了,你再走到这里时你又计数了一次。那如果没有写恢复现场的话,他就不会走原来走过的路的同时res++,因为他不符合新dfs的条件,所以不会进行dfs。这里回溯的同时如果遇到没走过的路,就res++。所以只要遇到没走过的路,res就++,所以就不会出现重复计数的情况。

2023-08-20 16:21:45 44 1

原创 DFS 例题

因为这里要放k个棋,按照常规思路的话,x只能从一开始搜,但是也有可能第一行没有放棋子,第二行才有棋子,所以这里的关键点在于第一行往下搜如果搜完了,那么就可以从第二行在继续放下搜,注意:这里的递归代码要写在for循环外面,并且棋子数是不能动的。

2023-08-20 16:02:02 36 1

原创 STL set和unordered_set容器详解

而STL的set采用的是红黑树的结构,可以保证快速高效地进行元素插入、删除和查找操作,并且在插入或删除元素时会自动调整树的结构,保证树的平衡性,所以STL的set插入与删除的时间复杂度是 O(log n),查找的时间复杂度也是 O(log n),这是数组所不能比拟的。vector也可以用来存储有序集合,但是它的插入和删除操作时需要移动一定数量的元素,这就使得它的效率不如set,时间复杂度是O(n),而STL的set是使用红黑树实现的,可以很快地找到插入和删除的位置,时间复杂度是O(log n)。

2023-08-15 12:21:23 104 1

原创 STL map和unordered_map容器详解

在map内部所有的数据都是有序的,因为map是由一颗红黑树实现的,这棵树具有对数据自动排序的功能。//返回关键字为"Alice"的数量,由于关键字唯一,所以只返回0和1。//这里没有关键字为20的元素,所以这里相当于创建一个关键字为20,且值从0变为1的元素。//删除关键字为"Alice"的元素。//此时friends[10]的值变为4。

2023-08-15 10:29:29 61 1

空空如也

空空如也

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

TA关注的人

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