数据结构进阶
菜鸡来喽!
北岭山脚鼠鼠
21岁,是大学生
展开
-
AC自动机——搜索关键词+单词
构建next数组过程,首先看回kmp算法里面的next数组的构建过程,在下图里面的j代表的具体意义实际上是next[i-1],也就是第i-1个字符与前缀的最大匹配长度,下面的while循环里面a[i]和a[j+1]的比较实际上就是第i个字符和第i-1个字符能够匹配上的最大长度的前缀的下一个进行比较,如果相同就能让第i个字符的next[i]==next[i-1]+1;ac自动机里面的next数组存的是以当前字母结尾的字符串与从开头开始的字符串的最大匹配长度的字符串的指针。思路:没想好,不写先。原创 2022-10-21 21:34:54 · 416 阅读 · 0 评论 -
可持久化数据结构——最大异或和(trie)+第K小数(线段树)
和可持久化trie树一样用一个root[i]表示第i个版本的线段树,线段树里面会存一个cnt表示前p个元素里面在tr[p].l到tr[p].r之间的元素的数量有多少个,要求[l,r]的原区间里面第k小的元素要用第r个版本的线段树的cnt减去第l-1个版本的cnt,这个结果才是数组区间[l,r]里面的元素统计的数量。与Trie的节点一样,可持久化trie的每一个节点也有若干字符指针指向子节点,可以用trie[x,c]保存节点x的字符指针C指向的子节点的编号。可持久化的trie可以查询历史版本的trie,原创 2022-10-20 22:42:08 · 413 阅读 · 1 评论 -
Treap树——营业额统计
利用treap树的两个操作,一个是查找大于x的最小数,一个是查找小于x的最大数,将代码稍微修改一下就是大于等于和小于等于。原创 2022-10-02 12:51:55 · 98 阅读 · 0 评论 -
Treap树的基本操作以及模板题目
选择左旋或右旋是需要进行判断的,要保持平衡树本身性质,将左右节点中val值较大的一个节点旋转上来。通过不断进行左旋或者是右旋将要删除的节点下放到叶节点的位置去。3.找前驱以及后继(找某一个节点的前驱和后继(一定存在))中序遍历依旧是AxByC ,但是x变成了y的父节点。8.比某个数大的最小 (这个数不一定是在树中)获取一个新的节点,其中val值需要用随机数函数实现。更新当前节点的子树计数,上传信息。Treap树里面的节点定义。6.求排名是k的数是哪个。7.比某个数小的最大值。5.求某一个值的排名。原创 2022-10-02 08:56:15 · 408 阅读 · 0 评论 -
树状数组——数组两种初始化方式+单点增加+查询前缀和+插入
长度为2^im的:[1+2^i1+...+2^i(m-1) , 1+2^i1+...+2^i(m-1)+2^im];对一个序列a,建立一个数组c,其中c[x]保存序列a的区间[x-lowbit(x)+1,x]中所有数的和。每一个区间的长度就是右边界R的二进制表示下的最小的2的次幂,记为lowbit(R)长度为2^i3的:[1+2^i1+2^i2,2^i1+2^i2+2^i3]长度为2^i2的:[1+2^i1,2^i1+2^i2]比如15=2^3+2^2+2^1+2^0。长度为2^i1的:[1,2^i1]原创 2022-09-15 21:44:17 · 615 阅读 · 0 评论 -
线段树基本操作——建树+单点修改+区间查询+懒标记下传
l=4,进入右子树后,立刻有1原创 2022-09-18 07:52:35 · 217 阅读 · 0 评论 -
线段树——花神游历各国(单点修改+优化)
思路:原本应该是能用懒标记来做的,但这里的修改有点特殊,开方,一堆数加起来后开方,和一堆数开方后加起来结果会有差别,根据大佬的题解得知,这里是能够用单点修改来代替区间修改的。根据来源于哪怕是1e9开方6次就会变成1(在开方向下取整的条件下)。当且仅当节点的p的两个子树的st值都为true时,节点的p的st值才能为true,表示该该子树已经不需要再做开方。在结构体里面加的多一个st标记用来表示该子节点或者该节点下的子树是否还需要做开方操作。所以哪怕是最差的时间复杂度,也是6*10^5次.原创 2022-09-19 18:44:23 · 262 阅读 · 0 评论 -
线段树——维护序列(两个懒标记的情况)
思路:这道题和一个简单的整数问题那道题2相比只是在原本的假发懒标记的基础上加多了一个乘法的懒标记,但这里的懒标记是有优先级问题的当两个懒标记或多个懒标记堆积在一起的时候先乘再加和先加再乘的结果是不一样的。因为新懒标记不会同时到来,只能一个一个传递,所以上面的函数中的每一次调用add为0要么mul为1;在已经有一个加法懒标记和一个乘法懒标记的基础上加多一个乘法的懒标记。在已经有一个加法懒标记和一个乘法懒标记的基础上加多一个加法的懒标记。所以本题的唯一难点就是在如何处理懒标记上。对于区间内的每一个数x都有。原创 2022-09-19 16:13:23 · 218 阅读 · 0 评论 -
线段树——区间最大公约数()
到这里,题目中还需要用到原序列a的数据,题目中只涉及到区间增加的内容,所以可以用一个树状数组维护原序列a的变化状况。如下题就是一个区间增加+单点查询的问题。思路:由更相损减术的公式gcd(a,b)=gcd(a,b-a) 扩展到三位数的情况gcd(x,y,z)=gcd(x,y-x,z-y)联想到,题目中的求最大公约数也可以这样做,使用一个差分数组来代替。至于差分数组的变化则是使用线段树本身自带的单点修改。差分数组的好处是可以将原本的区间。询问区间公约数就是在求。的修改改为在差分数组。原创 2022-09-18 19:40:40 · 224 阅读 · 0 评论 -
线段树——你能回答这些问题吗?(经典应用)
随便来点原创 2022-09-18 13:00:51 · 232 阅读 · 0 评论 -
树状数组——校门外的树进阶版
如果要求求某一段区间[l,r]内的树的种类,那就是拿r(及其自身)前面的所有左括号的数量减去l-1(及其自身)前面所有右括号的数量。容易想到最终得到的数字就是区间内的树的种类。这一点可以用两个树状数组实现,两个数组的前缀和sum[i]分别用来表示位置[i]前面的左括号的数量和位置[i]前面的右括号的数量。思路:利用括号序列的思想,设一段种树的区间由一个左括号和一个有括号括起来。左括号的位置是l, 右括号的位置是 r.原本的是求一段区间内的树的数量,现在求的是一段区间内树的总数。原创 2022-09-17 20:26:34 · 123 阅读 · 0 评论 -
树状数组——谜一样的牛
思路:题意转化一下就是,建立一个初始为1的01序列c,从后往前扫,每一头牛的身高就是在序列c中第a[i]+1个1出现的位置下标。原创 2022-09-16 22:44:26 · 90 阅读 · 0 评论 -
树状数组——一个简单的整数问题2(树状数组做法+线段树做法)
结合上述的全部需要做的操作就是,建两个树状数组c0和c1,一个用来存上图中红加黑的部分,一个用来存红色的部分。思路:原本简化版的是区间增加和单点查询,先在变成了去区间增加+区间查询,难度瞬间上升。2.在c1中,c1[l]+=l*d, c1[r+1]- =(r+1)*d;1.在c0中 ,c0[l]+=d , c0[r+1]- = d;到这里后对于某一个区间[1,x]增加的值就是。,这里求的是区间内整体增加的数值。在原本的问题里面,b数组的前缀和。就是增加过后a[x]增加的值。靠c1和c0就可以做到。原创 2022-09-16 21:48:32 · 286 阅读 · 0 评论 -
树状数组——一个简单的整数问题
在r-l范围内的每一个数都走一次增加操作,每一次这样操作的最差的时间复杂度是O(NlogN),操作有100000次,10^10次方差不多,铁超时。反映到序列a上就是序列a对应位置的变化,如要查询x处的数值,就可以用原序列a[x]的值加上c[x]处就是经过一系列增加操作后的x处的数值。首先最简单的一个思路就是维护给出的序列a的前缀和,然后在根据给出的 l,r,x;到这里我们可以将做法从“维护a数列的具体数值”转变为“维护增加指令带的影响”。c[x]在这里的具体含义是一系列的增加操作对位置为x的数的变化。原创 2022-09-16 20:34:45 · 205 阅读 · 0 评论 -
树状数组——楼兰图腾
以v为例,设left[i]是元素a[i]左边的元素中比它大的元素的个数,设right[i]是元素a[i]右边的元素中比它小的元素的个数。v的个数很明显等于所有left[i]*right[i]的和。而left数组和right数组的构造可以采用树状数组求逆序对的方法来求的。^的情况类似,不再解释。原创 2022-09-15 23:20:43 · 100 阅读 · 0 评论 -
树状数组——逆序对(范围较小)
这里倒序查找的内容就是上面说的数组t的[1,a[i]-1]的区间和,即在序列中。用一个t[x]数组记录数值x在序列a中的出现次数,那么可以得知数组t。的任意区间[l,r]就表示集合a中范围在[l,r]内的数有多少个。在a的数值范围内建立一个树状数组,用以维护t的前缀和,可以做到。排在a[i]后面的元素比a[i]小的元素的出现次数。1.首先由序列a的最大元素大小确定树状数组的大小。(1)查询前缀和(a[i]-1)累加到ans中。在序列a中插入或删除一个数时还能高效的统计。同时将c[a[i]]++原创 2022-09-15 22:40:28 · 172 阅读 · 0 评论 -
并查集——奇偶游戏(带边权和扩展域做法)
证明:s[l,r]里面的奇偶性可以由sum[r]-sum[l-1]得到,s[l,r]有偶数个1,说明sum[r]-sum[l-1]要么是两个偶数,要么是两个奇数。否则得不出s[l,r]里面是有偶数个1这个结论。有ans=d[x]^d[y]^d[pa]可以得到d[pa]=ans^d[x]^d[y];[l,r]里面有奇数个1的情况下说明,sum[l-1]与sum[r]的奇偶性不同。证明和上面类似,此处略。可以发现假如题目给的一个范围[l,r]里面有偶数个1,等价于sum[l-1]与sum[r]的奇偶性相同,原创 2022-09-14 20:39:14 · 807 阅读 · 0 评论 -
并查集——银河英雄传说()
使用并查集可以传递关系的性质,维护一个cnt[i]数组,该数组用于记录以i为跟并查集树下的战舰的数量,用一个d[i]数组表示在i前面的战舰的数量。d数组和cnt数组的维护可以在get函数和merge函数时实现。原创 2022-09-14 19:18:56 · 178 阅读 · 0 评论 -
并查集——程序自动分析
题目的两两元素之间相等可以用一个并查集树来表示,在一个并查集树中所有的元素的都是与根节点相等的,先走一遍所有的条件,按要求一个一个实现后再走一遍,假如有哪一个不符合的话说明该问题不能被满足。原创 2022-09-14 18:50:47 · 75 阅读 · 0 评论 -
并查集——搭配购买(并查集+01背包)
思路:所有需要一起购买的物品通过并查集的方式将价钱和价值都合并到根节点处,到最后,每一个根节点是自身的节点就是我们的01背包当中的物品。原创 2022-09-14 18:46:57 · 117 阅读 · 0 评论 -
并查集——格子游戏(简单应用)
思路:将图上的每一个点都用他们的坐标转化成一个具体的数字表示做一个点,如 (x,y)可以表示成a= x*n+y。每次向右和向下扩展的时候就相当于将两个点所在的并查集树合并,在合并之前要判断他们的根节点是否相同,如果相同的话就说明已经出现环了。如果在某一步就直接的跳出循环,那剩下的那些没输入的数据有什么用吗?原创 2022-09-14 18:43:06 · 977 阅读 · 0 评论