数据结构
yzyyylx
这个作者很懒,什么都没留下…
展开
-
vector的用法
介绍 vector是C++标准模板库,是一个容器,可以理解为动态数组。 命名空间为std,所属头文件为 注意:不是 < vector.h > vector存储数据时,会分配一个存储空间,如果继续存储,该分配的空间已满,就会 分配一块更大的内存,把原来的数据复制过来,继续存储,这些性能也会一定程度上会>有损耗。vector常用方法1.容量 a.vector大小:vecto转载 2017-10-18 20:59:54 · 315 阅读 · 0 评论 -
虚树
作用针对有q次询问,每次询问树上的m个点的信息的题目,如世界树,可以每次将询问的这些点和这些点两两之间的lca(O(m)个点)单独拿出来建一棵虚树,然后在虚树上贪心或是dp来解决,其复杂度为询问总点数*log询问总点数+在虚树上操作的复杂度.建法首先将所有询问点按dfs序排序,用栈维护刚刚扫过的一条链,然后求出此时要加入的点与栈顶节点的lca,然后不断pop(并且在pop的同时加边)直到栈顶元素为l原创 2018-03-26 20:17:15 · 227 阅读 · 0 评论 -
无旋treap
作用一种平衡树,可以只利用合并与拆分两种操作实现插入删除等所有二叉查找树可以做的事情.实现方法treap=tree+heap,利用tree来保持二叉查找树的功能,再利用heap来保证它是平衡树. 每个节点保存两个值,一个是题目给出的,要储存的值,还有一个是rand的且长期不变,建树时储存的值根据二叉查找树的性质来保存,同时保证rand()的值符合堆的性质,每个根为该子树的极值,这样就可以保证树的平原创 2018-03-14 14:40:14 · 305 阅读 · 0 评论 -
后缀自动机
作用常用于处理字符串问题,可以高效解决许多字符串问题。实现方法有点像将一个字符串的所有后缀都建在一个AC自动机上,但不同的是后缀自动机的节点数最多为2*n,因为它只记录需要记录的点,一些没有记录东西的点可以视为与下面有价值的节点并在一起,这样大大降低了时间复杂度和空间复杂度。 对于每一个节点记录它的后面加上每个字符后后缀最长可以到达的节点,以及它的长度len,它去掉一个最短前缀后存在的节点pre。原创 2018-03-14 23:47:47 · 332 阅读 · 0 评论 -
AC自动机
作用用于处理多个字符串匹配,例如给出一些关键单词,再给出一篇文章(或多篇),问文章内的出现了几个单词或一共出现了几次.实现方法可以说是KMP与字典树的结合,就好像利用字典树存储多个字符串的next数组. 首先将所有关键单词建一棵字典树,每个节点除了存储26(字符种类数)个儿子外,还要储存sum和fail. sum用于记录此节点是否是某个关键词的尾字符,并且也可以顺便储存此字符串的个数 fail原创 2018-03-13 19:37:10 · 194 阅读 · 0 评论 -
树状数组
作用 可以用于单点修改和区间查询,且空间较少,时间复杂度为(n*log(n)).做法 顾名思义,树状数组本质上是一棵树,详见下图(网上找的). C数组表示要记录的数组,A数组表示每个点的数字,而在实际操作时只要记录C就行了,注意C[n]表示的并不是1~n的和. 上图可以转化为下图: A,C数组间的关系见下图: 修改 当我们要修改某个点时,只要修原创 2017-12-02 11:23:38 · 270 阅读 · 0 评论 -
可持久化并查集
介绍可以查询并查集的历史版本,即几次操作之前的连通状态,有在线与离线两种不同算法.离线算法相比于在线算法,时间复杂度与空间复杂度均要优越得多,若要查询第k次操作之后的状态,则可以视为k节点与此节点相连,否则视为上一节点与此节点相连,则这样将会形成一棵树,记录时用启发式合并,将较小树向较大树合并,而且不进行路径压缩,这样复杂度为O(n*logn),dfs一遍即可.代码(以洛谷 P3402 【模板】可持原创 2018-03-22 18:48:15 · 265 阅读 · 0 评论 -
主席树
作用 用于查询区间第k小值等,本质是线段树,因为是某个主席发明而得名,算法内容与主席无关.实现方法 线段树维护序列的值的个数,并对每一个前缀建一棵线段树(主席树不是这样的,否则空间…),那么要查区间[l,r]就只需要将r这棵树减去(l-1)这棵线段树,在相减后的线段树查找即可(实际不需要再建一棵树). 空间优化:根据上述方法,可以发现相邻两棵线段树的区别只有log,因而后面的线段树可原创 2018-01-24 18:06:01 · 201 阅读 · 0 评论 -
可修改主席树(树状数组套主席树)
作用 普通主席树可以查询区间k小值,但若直接修改,则复杂度极大,而可修改主席树通过树状数组的辅助来修改,大大缩小了时间复杂度,缺点是空间复杂度过大. 修改的时间复杂度为O((logn)^2),空间复杂度为O(n*logn^2).实现方法 为了减小修改复杂度,可以修改每个区间管理的范围. 传统主席树每个点对应的主席树管理一个前缀,而可修改主席树因为树状数组在处理动态区间和上有优势原创 2018-01-26 19:57:39 · 595 阅读 · 0 评论 -
Histogram LightOJ - 1083(RMQ)
题面题意 有一串由矩形组成的图,先要求出这幅图中所能容纳的最大矩形的面积总体思路 求出以各个小矩形高度为宽所能达到的最大面积,此时我们称这个最大矩形被这个小矩形统治,我们只需求出每一个小矩形统治的最大矩形的左端点和右端点.法1(单调栈)方法解释 让矩形依次入栈,当入栈矩形小于栈顶时,说明此时的栈顶不能统治该矩形,其右端点即为入栈矩形的位置-1.最后将让元素全部出栈,它们的右端点均为这原创 2017-10-21 13:20:46 · 285 阅读 · 0 评论 -
Palindromic Tree 回文自动机-回文树
作用回文自动机,顾名思义,用于解决回文串的问题,可以用于处理回文串的数量,种类数等问题.构造方法与其他自动机差不多,一般记录son[字符个数] (在左右两边加入某字符后匹配的节点),len(长度),fail(失配后所到达的节点,也就是这个回文串的最长回文后缀). 一开始有两个节点,长度分别为0(偶数长度的回文字符串的起始点)和-1(奇数长度的回文字符串的起始点,定为-1可方便后面的计算) 新加入原创 2018-03-29 19:42:04 · 301 阅读 · 0 评论 -
堆(优先队列)
优先队列简介作用代码优先队列简介 是一个完全二叉树(除最后一行外,其余部分为满二叉树),且父亲永远比孩子大或小。 用一个数组实现i的孩子为i*2和i*2+1,父亲为i/2。作用 1.迅速输出最大值,用pop输出数组的第一位 输出第一个,并把最后一个提上来,并比较使之合法 2.用——.push输入 先加到数组尾,再与父亲比较,过大则交换 3.用——.emp原创 2017-09-08 21:18:07 · 268 阅读 · 0 评论 -
Social Net ZOJ - 3649
题意给出一幅有n个点的连通图,求出它的最大生成树,之后对于m个询问,每个询问包括两个数ab,求出a到b的路径上的极差最大值(必须用后面的数来减前面的)方法首先求出最大生成树,之后找到LCA,即可由它得到路径,但是发现暴力扫整一条路径肯定会TLE,因而可以用倍增的方法来预处理 dad[i][j]表示i节点的第(1 &lt;&lt; j)的父节点(即父节点的父节点的父节点,重复(1&lt...原创 2017-10-30 12:56:53 · 330 阅读 · 0 评论 -
单调队列
解释 队首为一段区间的极值,可以通过不断地push来更新以push进去的数为末尾长度为k的最小值.实现方法 加入元素时,区间也在不断地向右移动,故若队首的位置小于区间的左端点,去掉队首. 或者当加入元素小于等于队首时(取区间最小值时),去掉队首,因为加入元素比队首小,且位置更靠后,后面还会有利用的机会,而队首左边的区间极值已经处理完毕,剩下的利用机会都和加入元素在一起,故去掉它毫无影原创 2017-10-24 10:22:43 · 205 阅读 · 0 评论 -
笛卡尔树
性质二叉树,其中的每一个点是整棵树的极值,且每一棵树的中序遍历是原数组的一段。 详见下图: 建树方法每次加入到树的最右节点,若不符合其规范,沿着右边那一条链向上找,将它插入到恰好符合的那一个点的左节点,并且将那一段不符合的点加入到新加入点的右子树,并且更新右边那一条链。 例题代码scanf("%d",&amp;n); for(i=1;i&lt;=n;i...原创 2017-10-23 20:35:38 · 523 阅读 · 0 评论 -
单调栈
解释 单调栈就是一个栈中的所有元素都依次递增(或递减),若入栈元素不符合,则不断出栈(根据题目记录下需要信息),直到它符合条件,并根据题意记录需要信息,最后让元素全部出栈并记录信息. 可以先向栈加入一个为0或为无限大的元素(据增减性而定),使当栈为其他元素时,任意元素都可以进栈,而省去了对栈顶是否为空的判断. 最后让所有元素出栈时,也可采用相同方法,加入一个极端元素来实现.原创 2017-10-21 13:07:28 · 237 阅读 · 0 评论 -
HDU - 1754 I Hate It (树状数组维护区间最值)
题面题意 给出一列数,有两种操作: 1.修改一个数 2.询问区间最大值方法 用树状数组来维护区间最值,复杂度为O(n*(logn)^2). 做法与维护区间和不同,因为修改最值时无法求出新的最值,但是维护的区间相同. 树状数组维护的区间是[u-lowbit(u)+1,u],可以据此来进行这些操作.修改 若sz[i]之前的值都正确,则可以发现C[i]可以用这段代码原创 2018-01-16 11:58:21 · 421 阅读 · 0 评论 -
树状数组维护区间和和区间修改
作用 可以用树状数组在(n*logn)内,虽然线段树也能,但是树状数组的代码,空间都要比它优越得多.实现方法 首先我们可以用差分的方法使区间修改可以在log的复杂度完成,但重点在于区间和的查询. 我们知道,此时num[i]=a[1]+a[2]+……a[i],可以利用树状数组快速求出. 而区间和则是(a[1]+a[2]+……a[i])+(a[1]+a[2]+……a[i-1])……原创 2018-02-08 19:53:23 · 493 阅读 · 0 评论 -
K-D Tree
作用一种用于储存多维数据的数据结构,同时可以查询多维空间中距离它最近的一个点.做法build首先它是一棵二叉树,而每一层用不同维进行分组,标准写法是每次求出每一维的方差,选取方差最大的那一维作为比较依据(后面与二叉查找树相同),找到这一维的中位数,分成两组,然后递归建树,复杂度为O(n*(logn)^2). 但实际上可以rand()一维再rand()一个分界点,之后比它大的放左子树,比它小的放右子原创 2018-04-13 20:25:27 · 285 阅读 · 1 评论 -
带花树
作用 求二分图的最大匹配可以用匈牙利算法来做,但是一般图则就要用带花树. 因为二分图中只有偶环(有偶数条边的环)而没有奇环,若用匈牙利算法则会出现一个点存在于两个匹配中或是遗漏情况(匈牙利算法在查找中只会在答案增加时替换,不会直接替换). 因此相比于匈牙利算法,带花树有针对奇环的操作.实现方法 每次搜索先取一个未匹配点,以它为起点,并对其进行标号(1或2,其他点的原创 2018-01-18 19:46:32 · 312 阅读 · 0 评论 -
图的输入及其边的记录(邻接表)
代码正解#include <bits/stdc++.h>const int N = 1e5+10;const int M = 1e5+10;using namespace std;int E = 0,n;int to[M],nxt[M],fst[N];void add(int e,int v){ to[++E] = v; nxt[E] = fst[e]; fst原创 2017-09-05 19:25:11 · 896 阅读 · 0 评论 -
APIO2018 新家
题面题意在一条路上有n家商店,每个商店有一个类型,在某段时间内在某个位置上存在,每次询问给出一个时间和一个地点,求该时间从该地点出发最少走多少路才可以到达任意一种类型的商店。做法首先可以离线处理,根据时间进行排序,那么没家商店就都可以看作是在某个时间加入,再从某个时间删除,并询问某个点到所有类型点的最小距离的最大值。这个可以进行二分,这样问题就转化为了,询问此时某一段区间内是否存在所有类...原创 2018-12-29 21:56:41 · 515 阅读 · 0 评论