
数据结构
迷亭1213
帅帅帅
-
原创 树与二叉树
本文主要整理数据结构中和树相关的重要或较难的知识点,仅供个人复习。二叉树的主要性质1)非空二叉树上叶子节点数等于双分支节点数+1。2)二叉树的第 i 层上最多有 2i−1(i>=1)2^{i-1}(i >=1 )2i−1(i>=1) 个节点。3)高度(深度)为 k 的二叉树最多有 2k−1(k>=1)2^k - 1 (k>=1)2k−1(k>=1) 个节点。4)有 n 个节点的完全二叉树,对各个节点从上到下、从左到右依次编号(1~n),节点之间有如下关系:.2020-08-02 17:29:45101
0
-
原创 KMP中几种Next数组的求法
今天复习到 KMP 算法时候发现考研教材上的 Next 数组和我之前学的不一样,所以特地拎出来比对一下,顺便总结。因为我之前掌握的 KMP 是李煜东的《算法竞赛进阶指南》上介绍的,而考研教材似乎更多用的是严蔚敏的《数据结构(C语言版)》,所以就对这两种实现方式做整理。竞赛版设 P[i , j] 为模式串 P 从 i 到 j 位置上元素构成的子串,t 为当前子串中真前缀与真后缀的最长匹配长度。假设字符串从下标 1 开始存放,即 P[1 , n] 为模式串。nex[i] 表示“P 中以 i 结尾的真后2020-07-14 19:58:47238
1
-
原创 C 语言中指针的常规操作
前言虽然在算法竞赛中很少用到指针,因为指针一般都有其它结构可以代替,并且指针很容易出错且难以发觉;不过在考研中似乎指针是绕不开的,并且在底层设计中 C 语言的指针确实有着速度优势,因此本文将整理有关指针的常规操作,包括指针的基本用法、利用指针实现链表、树与图中的指针等,不照顾毫无 C 基础的。既然考研中用 C 和 CPP 答题都可以,那本文就用 C++ 语法。指针的声明与赋值指针的声明方法这应该是 C 语言基础知识中的,下面四个指针声明语句都是正确的: int* p1; int*p2; in2020-06-30 17:04:32205
0
-
原创 长链剖分
长链剖分简介长链剖分属于树链剖分的一种,可以把维护子树中只与深度有关的信息做到线性时间。一般的树链剖分是指剖分轻重链,其依据子节点的个数进行剖分,可以使得我们可以在任意一个点向上跳跃不超过 log 次就能到达根节点,从而可以高效维护两点之间的链的信息。而长链剖分则是依据子树的深度进行剖分,深度最大的作为重儿子,这样原树就可以被分成若干条互不重复的链,并且保证了重链尽量长。因此长链剖分可以维...2020-02-16 10:46:45317
0
-
原创 2019CSP-J普及组复赛题解
A.数字游戏题意描述小 K 同学向小 P 同学发送了一个长度为 8 的 01 字符串来玩数字游戏,小 P 同学想 要知道字符串中究竟有多少个 1。 注意:01 字符串为每一个字符是 0 或者 1 的字符串,如“101”(不含双引号)为一 个长度为 3 的 01 字符串。解题思路签到题。代码示例#include<bits/stdc++.h>...2019-11-26 20:09:036996
0
-
原创 CodeForce #600(Div2) 解题报告
A. Single Push题意简述:给定两个序列 a 和 b,要求从序列 a 中选出连续的一段[l , r] ,对这段上的每个位置+k(k >= 0),试问只操作一次能否使得序列 a 变为序列 b 。解题思路:由于只能操作一次,所以难度大大下降,因此只需要顺序判断 a 是否只有一个区间和 b 不同,且差值全部相同且为负。代码示例:#include<bits/stdc++....2019-11-24 12:30:4389
0
-
原创 树链剖分题集
树链剖分常用于处理静态树上操作,效率很高,写起来也就是固定的轻重边拆分+线段树,但是代码一般都是100行+,容易出错。本题集中的树链剖分练习题,在解决思路上没什么难点,主要是如何设计线段树以及如何更新+询问,也就是说要想好怎么维护线段树,其它地方没什么太难的,但是代码长就容易出bug,多写写就好了。最后一题是线段树动态开点,这和可持久化权值线段树(动态主席树)一样的思想,只需要将普通的线段树给稍...2019-10-12 14:33:181184
0
-
原创 st表
摘要ST表是一个用来处理区间最值查询(Range Maximum/Minimum Query)的离线算法。该算法分为离线预处理O(n log n)和查询O(1)两个部分,其用到了倍增的思想。某个区间查询问题是否适用ST表,关键在于其进行的操作是否允许区间重叠,例如max(a,b,c) = max{max(a,b),max(b,c)}就可以用ST表维护,而区间和问题则不能维护。问题描述给定一...2019-07-16 18:31:161352
3
-
原创 生成树相关问题整理
摘要:在对最小生成树算法有一定理解后,我们对典型的最小生成树题型应该不难解决,但是对于由最小生成树模型变形而来的几种模型,我们仍需做一次总结与记录。首先我们需要提出最小生成树几个性质,便于推导算法;然后我们将介绍6种最小生成树相关问题模型,并讨论一般解法与更优解法;其中有的解法显而易见,接受起来也很简单,但有的解法却需要从理论上逻辑严密的进行推导,构造算法并证明算法的正确性,这部分难度稍大。...2019-07-14 22:30:42129
0
-
原创 莫队算法
莫队算法摘要莫队算法大概有基础莫队、树形莫队、带修(带修改的)莫队等类型,本文仅介绍基础莫队。可以看作莫队算法的入门。莫队算法据说是2010年国家集训队的莫涛发明的一个优化类的算法,由于莫涛经常打比赛做队长,大家都叫他莫队,该算法也被称为莫队算法。它使用指针移动以及分块的思想对朴素算法进行优化。莫队算法是离线算法,可以解决一类离线的区间问题,对于序列上的区间询问问题,如果从 [l,r] 的...2019-07-14 22:29:06225
1
-
原创 关押罪犯 解题报告
4901 关押罪犯 0x49「数据结构进阶」练习描述S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N。他们之间的关系自然也极不和谐。很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突。我们用“怨气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多。如果两名怨气值为c 的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并造成影响力...2019-06-11 16:03:41269
0
-
原创 “扩展域”与“边带权”并查集
前置知识并查集路径压缩与按秩合并“边带权”并查集并查集实际上是由若干棵树构成的森林,我们可以在树中的每条边上记录一个权值,即维护一个数组d,用d[x]保存节点x到父节点fa[x]之前的边权。在每次路径压缩后,每个访问过的节点都会直接指向树根,如果我们同时更新这些节点的d值,就可以利用路径压缩的过程来统计每个节点到树根之间的路径上的一些信息。这就是所谓“边带权” 的并查集。例题:P...2019-06-11 15:20:03662
0
-
原创 图与树的存储方式
邻接表方式head与nex数组中保存的是ver(vertex)数组的下标,相当于指针,其中0表示指向空。ver数组中存储的是每条边的终点,是真实的图数据。也可以将head与nex数组看作存放边的编号(即tot)。#include<cstdio>const int MAXN = 100010;int head[MAXN],ver[MAXN],edge[MAXN],nex[MAXN...2019-05-05 15:57:57517
0
-
原创 Treap笔记
Treap是是英文Tree和Heap的合成词,又称树堆。树堆是指具有随机附加域,且附加域满足堆性质的二叉搜索树。它属于平衡树的一种,主要是为了克服二叉搜索树易退化的情况。Treap利用“随机”来创造平衡条件,我们在插入每个节点时,除了其值val,我们还给它随机附加一个权值dat,使得权值val满足BST性质,而dat满足二叉堆性质。如此一来我们就保证了树的深度,使得检索、插入、求前驱、后继以及删除...2019-04-24 13:30:2573
0
-
原创 洛谷P3369 普通平衡树
洛谷P3369 普通平衡树题目描述:您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:插入x数删除x数(若有多个相同的数,因只删除一个)查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)查询排名为x的数求x的前驱(前驱定义为小于x,且最大的数)求x的后继(后继定义为大于x,且最小的数)解题思路:由于数据范围很大...2019-04-28 20:23:2296
0
-
原创 洛谷3391-伸展树模板
题目描述您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1输入格式:第一行为n,m。n表示初始序列有n个数,这个序列依次是(1,2,⋯n−1,n); m表示翻转操作次数。接下来m行每行两个数 [l,r] 数据保证 1 ...2019-04-28 12:06:04106
0
-
原创 树上点分治
点分治就是在一棵树上,对具有某些限定条件的路径静态的进行统计的方法。前置知识:树的重心树的DFS序数组模拟邻接表存树对树的操作常见两种:边分治、点分治。对于点分治,顾名思义,就是要按照点进行划分,利用递归来实现分治。如果给定一棵树,以及树上的两个节点x和y,那么“序列上的区间”相对于的就是“两点之间的路径”。例题:POJ1741Tree给一颗有N个点的树,每条边都有一个权值。树...2019-04-22 20:35:02119
0
-
原创 伸展树(Splay)理论-笔记
简介前置知识:树->二叉搜索树->平衡树->AVL树->Treap->伸展树左单(双)旋、右单(双)旋、左右双旋伸展树(Splay Tree) 是平衡二叉查找树的一种,具有二叉查找树的所有性质;伸展树又称Self-Adjusting Search Trees,即自调整的二叉搜索树 。与普通的二叉查找树相比,其维护更少的节点额外信息,空间性能更优且编程复杂度...2019-04-26 19:05:57264
0
-
原创 后缀数组的计算
什么是后缀数组字符串后缀(Suffix)指的是从字符串的某个位置开始到其末尾的字符串子串。我们认为原串和空串也是后缀。反之,从字符串开头到某个位置的字符串子串则称为前缀。后缀数组(Suffix Array)指的是将某个字符串的所有后缀按字典序排序后得到的数组。不过数组中并不需要直接保存所有的后缀字符串,只要记录对应的起始位置就好了。后缀数组的计算假设我们要计算长度为n的字符串S的后缀数组。...2019-08-04 16:36:04244
0
-
原创 高度数组与最长公共前缀
摘要本文是关于后缀数组的一个拓展,问题模型来自于最长公共前缀(Longest Common Prefix Array)问题,我们为解决该模型,在后缀数组的基础上设计了一个精巧的数组——高度数组,同时由于该数组在处理各类字符串相关问题时有着较好的用途,因此值得掌握。本文将直接从高度数组讲起,假设读者具有后缀数组的基础知识。首先本文会介绍高度数组的定义以及用途,接着讲解如何在O(N)时间内求出高度...2019-08-04 16:36:50130
0
-
原创 树链剖分笔记
摘要树链剖分是用来维护静态树上路径信息的数据结构,静态即树的形态不能改变(增删点或者换根,改变了构造)。其思想是将树上的路径分为重路径和轻边,然后为每个节点分配一个编号,重路径上节点的编号是连续的;接着对这些编号建立一棵线段树,这样就可以将重路径当作区间来维护了;利用了“每个点到根的路径上都有不超过O(logN)条轻边和O(logN)条重路径”结论来保证时间复杂度。算法简介树链剖分通常用于...2019-10-10 13:40:2486
0
-
原创 树上倍增LCA题集
树上倍增法可以用于求LCA,当然在其它场合也有应用,在很多时候看似不是树形的问题,我们也可以通过转化成树形结构,然后在树中进行操作,这种操作可以是求二者之间的最近状态,或者是二者之间的距离,如最后一题。另外关于树的题型,最好还是根据样例画图思考,往往可以比空想获得更多思路。点的距离题意简述给定一棵 n 个点的树,Q 个询问,每次询问点 x 到点 y 两点之间的距离。解题思路模板题,用树...2019-10-09 20:21:10152
0
-
原创 线段树题集
区间和题意简述给定一数列,规定有两种操作,一是修改某个元素,二是求区间的连续和。解题思路线段树单点修改,区间查询的模板。代码示例#include<bits/stdc++.h>using namespace std;const int N = 1e5+10;typedef long long ll;struct SegmentTree{ int l,r; ll d...2019-10-07 17:52:101217
0
-
原创 一维RMQ问题题集
书本配套OJ本校OJST表使用说明:常用于离线问题,或当作辅助数据结构,查询时间非常优秀,O(1)二维st表也很好实现,不过本题集中未涉及st表内也可以维护的是下标而非值,在某些时候很有用数列区间最大值题意简述输入一串数字,给你 M 个询问,每次询问就给你两个数字 X,Y,要求你说出 X 到 Y 这段区间内的最大数。解题思路st表模板题。代码示例#include<...2019-10-07 13:11:46256
0
-
原创 树状数组题集
书本配套OJ我校OJ树状数组知识点:单点修改,区间求和,O(logN)。区间修改,区间求和,O(logN)。二维树状数组单点修改,子矩阵求和,时间复杂度O(logN * logN),空间O(N^2)。与线段树相比功能比较单一,不够灵活,但胜在简短易写,可以用来打辅助。注意事项树状数组修改的下标不能为0,因为 lowbit(0) = 0,这就死循环了。注意树状数组的空间,这是...2019-10-06 20:48:20272
0
-
原创 Fish eating fruit
测试地址题意简述:树上任意两点之间的路径按照模 3 为 012 分类,将两点间距离加和,乘 2 即为答案。解题思路:可以采用树上dp解决,也可以点分治,这里先给出一种树上dp做法:dp[i][k] 表示距 i 模 3 为 k 的节点距离和。tc[i][k] 表示距 i 模 3 为 k 的节点数目。ans[k] 表示所有路径中模 3 为 k 的路径的总长度。目标答案是ans[k] ...2019-09-24 09:01:45221
0
-
原创 hdu6638 Snowy Smile-线段树维护最大子矩阵
题目链接Snowy Smile题意简述:给出平面上n(n <= 2000)个点,点的坐标在-1e9~1e9之间,试求出最大子矩阵的和是多少。解题思路:考虑数据范围,2e3个点离散化后可能会有2e3个,本题中各个点是离散的,所以用普通的动态规划比较麻烦,因此本题采用O(N2log2N)O(N^2log_2N)O(N2log2N)的线段树+枚举。我们对x,枚举所有可能的x[i]和x...2019-09-04 11:04:37179
0
-
原创 可持久化线段树(主席树)
摘要主席树,又称可持久化线段树,属于可持久化数据结构。“主席”这一名词是由于发明者缩写为HJT,和某位主席拼音缩写相同(有些牵强),故将该数据结构称为主席树。主席树既保留了线段树的灵活,也拥有了可持久化数据结构的特点,在处理某些特定问题时有着其它数据结构不具有的优势。本文将首先介绍什么是“可持久化数据结构”,随后介绍主席树的思想,关于代码实现将结合例题讲解。可持久化数据结构可持久数据结构...2019-08-29 20:23:12227
0
-
原创 降雷皇(最长上升子序列数量)解题报告
测试地址题意简述哈蒙有n条导线排成一排,每条导线有一个电阻值,神奇的电光只能从一根导线传到电阻比它大的上面,而且必须从左边向右传导,当然导线不必是连续的。哈蒙想知道电光最多能通过多少条导线,还想知道这样的方案有多少。解题思路第一问就是简单的LIS问题,即询问最长上升子序列的长度。第二问是询问最长上升子序列的数量,如果用暴力做法,只需要多开一个数组记录数量即可,时间复杂度O(N^2);实际...2019-08-24 15:54:40102
0
-
原创 二维st表
摘要我们知道一维的st表在经过预处理后可以在O(1)时间内查询任意区间的极值,虽然其是离线算法,但胜在代码短小易写。而在二维RMQ(区间最值查询)问题中,我们依然可以采用st算法解决问题,只不过我们需要从一维拓展到二维,当然适用范围依然是离线。二维st表仍然是用倍增思想,如果理解了一维的st表,那么对于二维的也不难理解。问题描述给定一个n* n的矩阵以及一个整数b和k,共有k次询问,每次询问...2019-08-04 16:39:28917
0
-
原创 倍增求LCA
LCA:即求一棵有根树中两个节点的最近公共祖先。树上倍增法树上倍增法是一个很重要的算法。除了求LCA外,在很多问题中都有广泛应用。设F[x,k]表示x的2k倍祖先,即从x向根节点走2k步到达的节点。特别的,若该节点不存在,则令F[x,k] = 0。F[x,0]就是x的父节点,除此之外,对于任意的1 <= k <= log n,F[x,k] = F[F[x,k-1],k-1]。这就...2019-08-04 16:37:5675
0
-
原创 POJ1151 Atlantis 解题报告(朴素算法+线段树解法)
POJ1151 Atlantis 0x40「数据结构进阶」例题描述There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfo...2019-04-16 17:31:46234
0
-
原创 POJ3764The xor-longest Path 解题报告
题意简述:给定一颗N个节点的树,树上的每一条边都有一个权值。从数中选择两个点x和y,把从x到y的路径上的所有边权xor(异或)起来,得到的结果最大是多少?解题思路:假设D[x]为从根节点到节点x路径权值的xor,那么很显然D[x] = D[father[x] ]。也就是说我们可以从树的根节点出发,通过一边dfs求出根到每个节点的D。而由于异或的特性,我们知道从节点x到节点y路径权值的xor,...2019-04-20 21:27:08122
0
-
原创 C/C++ 哈夫曼树与哈夫曼编码
个人笔记,仅供复习1.哈夫曼树1.1 定义: 带权路径长度(WPL):设二叉树有n个叶子结点,每个叶子结点带有权值W(k),从根结点到每个叶子结点的长度为L(k),则每个叶子结点的带权路径长度之和就是:WPL = W(1)*L(1) + W(2)*L(2) + ... + W(k)*L(k) 最优二叉树或哈夫曼树:WPL最小的二叉树 如上面三棵树,第三颗的WPL最小,所...2018-07-10 11:16:501331
0
-
原创 C/C++ 并查集及其优化笔记整理
个人笔记,仅供复习1.集合1.1 集合运算:交、并、补、差,判断一个元素是否属于一个集合。1.2 并查集:集合并、查某元素属于什么集合。1.3 并查集问题中集合存储的实现:用树结构表示集合,树的每一个结点代表一个元素2.对并查集的操作 2.1 查询:为了查询两个结点是否属于同一集合,我们需要沿着树向上走,来查询包含这个元素的树的根是谁。如果两个结点走到了同一个根,那么就...2018-07-12 11:32:15598
0
-
原创 Manacher算法笔记 C++
Manacher算法简介:1.作用:Manacher算法又名马拉车算法,用来求一个字符串中最长回文子串的长度。2.复杂度分析:时间复杂度为O(n)。算法核心思想:1.伪代码:假设str为待判断的字符串,len[ i ]数组存放以该 str[ i ] 字符为中心的最长回文子串的长度,mid为当前最长回文子串的中点,mx为当前最长回文子串的右边界,那么对当前位置 i 有如下伪代码:(此...2018-11-16 19:03:559444
0
-
原创 POJ1064(二分搜索)解题报告
原题链接:POJ1064题意简述:有N根绳子,它们长度分别为Li。如果从他们中切割出K条长度相同的绳子的话,这K条绳子每条最长能有多长?答案保留到小数点后俩位。解题思路:用二分搜索方法来判断。首先假定一个解,判断其是否可行,不断缩小解的范围,从而得出答案。本题可以使用实数域上的的精度控制(即设置eps判断)或者干脆循环个几百次来逼近精度。注意点:printf()保留小数位时四舍五入...2018-12-20 10:52:17529
0
-
原创 POJ2456(最大化最小值)解题报告
原题链接:POJ2456题意简述:求在1~N中选C个位置,每俩个位置之间距离最小的值最大化。思路:让距离最小的那个距离最大。可以看出来答案具有单调性,那我们就可以转求解为判定,用二分搜索来求结果。具体做法就是假定一个答案,再不断缩小答案范围,最终得到解。注意点:while循环内的判定条件需要仔细考虑,稍有改变就会有截然不同的结论。代码示例:#include<cstdio...2018-12-20 14:13:25514
0
-
原创 二分搜索算法笔记C++
1.背景1.1 结论在有序数组中查找某个值,或者在求最优解问题时,二分搜索非常有用。思想一般是先假定一个解,并判断是否可行,接着缩小解的范围继续判断。1.2 概念二分搜索法,是通过不断缩小解可能存在的范围,从而求得问题最优解的方法。在程序设计竞赛中,经常可以见到二分搜索法和其他算法结合的题目。2.二分搜索2.1思想二分答案转化为判定。一个宏观的最优化问题也可以抽象为函数...2018-12-20 15:14:18680
2
-
原创 kd-树笔记
以下内容均为本人近几天学习笔记,个人理解,并非完美答案,请抱着怀疑眼光阅读,如有错误请告知,感谢!1.kd-树简介1.1 特征:在任何情况下,kd-树都是一棵递归定义的平衡二叉搜索树1.2 用途:常用于范围查询,高效解决多维范围查询。例如:快速在校友数据库中找到1970-2000年毕业并且身高在170-190cm且性别为男的校友。2.kd-树的实现2.1 一维kd-树:一维...2018-10-05 19:42:488694
0