- 博客(19)
- 问答 (3)
- 收藏
- 关注
原创 线段树原理 and 例题
懒标记的意思是如果我们要修改的区间完全包括了当前节点的区间 那么在这个节点标记即可 然而多次修改的时候 如果当前节点区间并不是完全被包括了 那么我们就需要讲当前节点的懒标记给到其两个子节点而自己的懒标记清0为什么需要这样做呢?主要的原理就是我们把一个完全的区间看成一个根把区间分为左右两个 [l,mid] [mid+1,r]那么这就是它的左右子树 直到分的只有一个元素的时候就停止 一般情况下节点的个数就是N*4。如果当前节点的区间并不完全被查询区间包括我们就需要讲当前节点的标记给到左右两个区间。
2022-11-29 23:38:16
209
原创 二分图/二分图最大匹配(匈牙利算法)
从左边最上面的点开始加入左1匹配了右1到左2的时候2只能匹配右1 那么我们回溯到左1看左1是否有其他点可以匹配 如果有那么让左1匹配其他点 然后左2匹配右1(大体思路就是这样)我们把这些点分为两个集合 假设1为集合1 那么2为集合2 集合3为集合1 1为集合2。右边集合只能对应一个左边的点(一一对应) 最大匹配就是左边最多几个点和左边的一一匹配。左为集合1右为集合2 那么二分图的匹配就是 左边集合的点对应一个右边集合的点 而且。然后白色邻接点都是黑色 这就是一个完美的二分图!那么它的邻接点都是白色。...
2022-08-16 18:24:04
413
原创 图论最短路(模板/模板题)
我们目标是从1到5的最短路但是可以发现从2——>3——>4——>2这个环上总和是一个负数每多走一圈距离就变短一次所以这个1——5的最短路为-∞那么怎么判断呢 根据抽屉原理可以得知n个点里任意两个点的任意路程如果不经过重复的点那么边的个数一定小于n 那么可以根据此方法来判断负环 维护一个cnt数组表示从起点到当前点的最短路的边 只要出现一个cnt[i]>n就一定有负环出现值得注意的是 负环不一定从1点可以到达 所以我们要把所有的点都当作起点枚举一下寻找。...
2022-08-03 15:28:32
419
原创 散列表/哈希表 字符串的哈希
给定一个长度为nn的字符串,再给定mm个询问,每个询问包含四个整数l1,r1,l2,r2l1,r1,l2,r2,请你判断[l1,r1][l1,r1]和[l2,r2][l2,r2]这两个区间所包含的字符串子串是否完全相同。这个是一个对数组的操作方式和离散化相似或者可以称离散化为特殊的哈希表,主要的目的就是通过对数据的一定操作使得原本散列的数据排列在一个具有特殊规律的表上从而方便查找减少时间复杂度。第二行包含一个长度为nn的字符串,字符串中只包含大小写英文字母和数字。...
2022-07-25 20:08:41
224
原创 kmp形象理解
next[4]=2解释只看前四个字符abab那么它的前缀为a,ab,aba后缀为a,ab,bab显然有字符长度为1,2的时候相等(取最大)next[3]=1解释只看前三个字符aba那么它的前缀为a,ab后缀为a,ba显然只有字符长度为1的时候相等。可以看到我们已知蓝色两个区域相等右边蓝色又和左边蓝色相等那么粉色就和左边蓝色相等那么就可以让j移动到ne[j]next[2]=0解释只看前两个字符ab那么它的前缀为a后缀为b显然没有相等的。=p[j+1]前面的都相等那么。...
2022-07-18 13:54:33
114
原创 手动实现离散化
离散化同有的特征就是数据范围特别大 难以开数组实现 但是能够提出有用贡献的数很少我们就是利用这样一个特性而把它变成我们可以解决的问题有些时候离散操作是可以通过map实现的但是运行效率不高 难免出现超时所以要学习手动离散化的操作 通过模板题来讲解具体操作模板题:区间和题目描述:假定有一个无限长的数轴,数轴上每个坐标上的数都是 0。现在,我们首先进行 n 次操作,每次操作将某一位置 x 上的数加 c。接下来,进行 m 次询问,每个询问包含两个整数 l 和 r,你需要求出在区间 [l,r] 之间的所有数的和。输入
2022-07-14 16:34:26
271
2
原创 优先队列priority_queue
近期在学习一些容器和其应用算法 稍微做了一些总结优先队列又被叫做二叉堆或者堆因为其底层实现是靠排序二叉树来实现的是一个很实用的容器 一般的优先队列的题目都是一些思维题或者和贪心结合的题目 优先队列一般分为大根堆和小根堆意思就是从大到小排序和从小到大排序若要对结构体放入优先队列需要对...
2022-06-12 21:42:26
586
原创 八大排序之归并排序,快速排序,基数排序
排序的方法有很多大致就分为比较类的排序和非比较类的 比较类的主要就是冒泡排序,归并排序,而非比较类的主要就是基数排序,计数排序,桶排序归并排序归并排序大体采用的是一个分治的思路 我们把原有的数列从中间一分为二然后每一段继续进行分割直到无法再分的时候比较从上一级同一段里分出的两个子段如果前者小则将前者先放入我们预先准备好的辅助数列然后在放后者回到那么此时倒数第二层也就就是有包括两个元素的子序列的排序就已经完成了 然后我们在进行相同操作比较从从上一层同一段分出的两个子段 先放入大的然后在放入小的 逐层渐
2022-04-30 20:41:15
344
原创 简单背包问题的变形
刷题遇到的背包问题一定不是一个指向很明显的题目甚至大多数时间都需要我们在模板上做一些处理才能得到正解 那么下面简单介绍一些刷题遇到的变形题目1.求不超过要求高度的最高累加高度题目看起来很绕没关系我们直接上例题poj-3628这个题目是价值和重量一样的背包问题 没什么好说的我们任然按照背包问题做但是dp[i][j]表示的就是前i个牛高度和不超过j的最大高度和#include<iostream>#include<cstring>using namespace .
2022-04-20 19:33:59
1024
原创 动态规划之最长子串,最大连续序列和,最长回文子串
子串和子序列的区别在于子串是连续的而子序列是不连续的 学习了很久的动态规划问题 做了很多的题目我发现动态规划的突破口在于找到递推关系式也就成功的找到了转移方程 下面我们进入最长子串问题 先定义一个二维数组dp[][] dp[i][j]表示str[i-1]==str[j-1]那么如果str[i-1]==str[j-1]那么dp[i][j]==dp[i-1][j-1]+1如果当前两个相等那么直接就等于上一个的连续长度+1 如果不相等那么dp[i][j]=0;if(str1[i]==str2[j])dp[i
2022-03-29 13:02:10
1102
原创 c/c++基础缓冲区
昨日被一个朋友问道一些输入的问题提及到缓存区的时候才明白很多人对缓冲区的概念是很模糊 以至于偶尔会在输入操作上不明所以 何为缓冲区 这个概念最早出现是在我学习c语言的时候 个人理解我们在利用键盘输入数据的时候先进入的是缓冲区 形象一点说缓冲区像是一个屋子 这个屋子有两个门一个只能进 一个只能出 能进的门就是接收我们键盘输入的数据 只能出的门自然就是我们的输入语句了它 但是因为输入语句的限制一些数据我们是无法让其通过这扇门的例如我们在学习c语言的时候scanf语句#include<bits/..
2022-03-26 10:24:58
1103
原创 动态规划之最长公共子序列 最长递增子序列
最长公共子序列最长公共子序列很简单dp[i][j]分别代表str1的第i个字符和str2第j字符 那么如果当前字符相等那么即str1[i]==str2[j]那么dp[i][j]==dp[i-1][j-1]+1如果不等的话就比较麻烦了如果不等dp[i][j]=max(dp[i-1][j],dp[i][j-1])意思就是找str1前i-1个元素与str2前j个元素最大的子序列or意思就是找str1前i个元素与str2前j+1个元素最大的子序列那么我们就有了转移方程 if(str1[i]==str2[j]
2022-03-23 20:25:26
1282
原创 动态规划之完全背包问题
昨天搞完了0/1背包问题今天又学习了完全背包问题再次做一个总结 完全背包问题题想较于0/1背包问题区别就在于 0/1背包中的物品只能使用一次而完全背包问题的物品可以使用任意次 那么解题的方法也与0/1背包问题十分相似当我们在装入一个物品之后随着背包的体积继续变大我们可以继续往背包里装东西 所以转移方程相较于0/1背包发生了变化dp[i][j]=max(dp[i][j],dp[i][j-vol[i]]+value[i]]这个转移方程不难理解 其实完全背包相比的是当放入第k个编号为i物品的包的价值和没有放入第k
2022-03-19 21:01:55
349
原创 动态规划之0/1背包问题(动态规划入门)
动态规划很早以前就接触过但是因为太晦涩难懂一下子到现在才开始真正的学习到其中的道理,0/1背包问题是动态规划的入门类问题 比较好理解 首先我们要知道动态规划是用于解决最优解的问题 它是一种思想而不是一种固定的算法dp的问题解决一般分为三步 定义状态,转移状态,算法实现,个人认为其中转移状态是最难的好的那么我们开始引入例题进行更清晰的讲解 下面是一个背包问题的模板题“骨头收集者”带着体积为V的背包去捡骨头,已知每个骨头的体积和价值,求能察上面的二维表进背包的最大价值。N<1000,V≤
2022-03-18 22:57:38
1288
原创 基础博弈论(NIm,威佐夫,巴什游戏)
最近刚刚接触了基础博弈论 一开始感觉是一个非常难以理解的专题 看了几天别人的题解 写了几道题感觉稍微有了一点点的感觉 下面来总结一下几个常见的基础博弈1.巴什游戏最简单的那当然就是巴什游戏了题目是说有一堆石子A,B分别去取石子每一次可取的数目为1—m个最后没有石子可以去的人则为败方那么思路很简单 先想当有m+1个石子时候不论先手取多少个 后手一定可以一次性取完,所以后手一定赢 那么再思考如果有n*(m+1)个我们都可以让先后手保持这样的状态 先手取k个后手取m+1-k个保证每一个周期结束后数目仍然是
2022-03-17 00:23:15
5077
1
原创 并查集算法
并查集问题比较好理解,种类也不算很多,主要解决的问题为集合分类或者帮派,种族问题 例如在一个城市中有n个人,他们分为不同的帮派,例如a认识b,b认识c那么a,b,c就属于一个帮派我们需要根据给出的关系 算出他们中存在几个帮派 这种类似的题目都可以用并查集来解决 我们用一个数组来记录每一个人属于的集合(帮派)val[n]数组下标表示每一个人的编号而数组总记录的就是这些人所属于的集合首先我们需要对每一个人进行初始化val[i]=i,即每一个人一开始都是一个集合...
2022-03-14 20:52:14
542
1
原创 bfs算法
bfs从原理上来讲就是在初始状态把所有可行的操作一一进行操作,通过不断的尝试找到目标状态,举个例子就好比在一个水池中扔入一颗石子会溅起水波水波不断地向各个空间移动最终到达目的状态,又好比走迷宫一般在每一个节点把上下左右都尝试一遍之后找到出口 因为bfs需要不断地储存状态,取出之前存放状态,进行操作,再次储存,我们不难想到用队来进行储存;例题如下1312 “Red and Black”一个长方形的房间,铺着方形瓷砖,瓷砖为红色或黑色。一个人站在黑色瓷砖上,他可以按上、下、左、右方向移动到相邻的瓷砖.
2022-02-27 13:17:43
1303
2
原创 浅识c++中list的front,back,begin,end的区别
在学习list时候了解到一个东西叫做迭代器(interator),它在容器中的作用有点类似于指针是容器和操纵容器的算法之间的中介,迭代器可以指向容器中的某一个元素,通过迭代器可以读取其指向的元素,那么由此开始进入本文的中心,front是返回list中的第一个元素,back是返回list中的最后一个元素如下代码:list<int>a; for(int i=0;i<20;i++) { a.insert(a.end(),i); }cout<<"front=" <
2022-02-09 15:14:57
5593
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人