数据结构
文章平均质量分 78
ccDLlyy
不忘初心,方得始终
展开
-
线段树模板
//区间替换,区间求和 #include #include #include #include #include #include using namespace std; #define MAXN 100 #define middle (left+right)>>1 #define leftSon left,(left+right)>>1,root<<1 #define rightS原创 2017-04-22 09:53:07 · 419 阅读 · 0 评论 -
Trie/字典树(理论转自他人,代码自己实现)
理论原博文链接:点击打开链接 Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。 Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。 它有3个基本转载 2016-11-29 23:07:40 · 620 阅读 · 0 评论 -
HDU 2838 Cow Sorting(树状数组求逆序数)
题目链接:点击打开链接 树状数组求逆序数的一个模板题。 对于给定的序列,变为递增顺序,每个位置的数的交换次数即为该数组成的逆序对的个数,所以此类题转化为求每个位置的逆序对。num数组保存的为原始数据序列,a,b为树状数组,a用于正向遍历num,对于每个num[i],均从num[i]+1更新到n,即getSum(a,num[i])为比num[i]早出现的且小于num[i]的数的个数,即在该数左边原创 2017-07-17 00:25:58 · 428 阅读 · 0 评论 -
左偏树
左偏树(Leftist Tree)是一种可并堆(Mergeable Heap) ,它除了支持优先队列的三个基本操作(插入,删除,取最小节点),还支持一个很特殊的操作——合并操作 左偏树是一棵二叉树,它的节点除了和二叉树的节点一样具有左右子树指针( left, right)外,还有两个属性:键值和距离(dist)。键值是用于比较节点的大小。距离则是如下定义的: 节点i称为外节点(ext原创 2017-07-12 16:03:21 · 975 阅读 · 0 评论 -
HDU 4585 Shaolin(Treap)
题目链接:点击打开链接 题意: 少林寺的每个和尚均有编号和战斗等级,新来的小和尚均要和老和尚比试,从老和尚中选和自己的战斗等级相差最少的比,如果有两个,选比自己战斗等级小的和尚。每个和尚的编号和战斗等级均唯一。 其实这是个水题,直接用map即可,但为了练习Treap,采用Treap方法。 可以想到采用的数据结构要能动态的维护一个有序序列(战斗等级,由于战斗等级和编号为一对一映射,直接维护战原创 2017-07-21 11:43:46 · 416 阅读 · 0 评论 -
HDU 1892 See you~(二维树状数组的单点更新,区间求值)
题目链接:点击打开链接 二维树状数组单点更新,区间求值的入门题目: 一维树状数组的思想很容易应用到二维树状数组中,sum[i][j]表示一块矩阵的和,其中i - lowBit(i) 那么求以(x1,y1) (左下角) 和 (x2,y2)(右上角) 为对角线的矩阵的和为getSum(x2,y2) - getSum(x1 - 1,y2) - getSum(x2,y1 - 1) + getSum原创 2017-07-17 22:52:27 · 431 阅读 · 0 评论 -
树状数组
转载自:点击打开链接 感谢作者 树状数组,又称二进制索引树,英文名Binary Indexed Tree。 一、树状数组的用途 主要用来求解数列的前缀和,a[0]+a[1]+...+a[n]。 由此引申出三类比较常见问题: 1、单点更新,区间求值。(HDU1166) 2、区间更新,单点求值。(HDU1556) 3、求逆序对。(HDU2838)转载 2016-12-04 17:21:34 · 736 阅读 · 0 评论 -
AVL树(一种二叉平衡搜索树)
普通的二叉搜索树,深度不一定为为O(logn),那么则是不平衡的 如果不进行删除操作或进行极少的删除操作(可利用懒惰删除),提出一种解决方案,即AVL Tree,任意节点左右子树的高度差绝对值不超过1,规定空树的高度为-1,即一个单独节点的高度为0 当进行插入操作,插入过程同二叉搜索树,插入后,插入路径上节点的平衡可能遭到破坏,从插入点到根结点的路径上(即自下而上)找到第一个失去平衡的节点原创 2017-01-21 20:14:06 · 814 阅读 · 0 评论 -
HDU 1394 Minimum Inversion Number(线段树求逆序数)
题目链接:点击打开链接 题意:一个序列,每次第一个数放到最后位置的过程中,最小逆序数为多少; 思路:先算出原始序列的逆序数,再按照放的过程算最小值 // HDU 1394 Minimum Inversion Number.cpp 运行/限制:31ms/1000ms //此题用线段树计算逆序数,此题求的为总逆序数,而不是每个位置的,因此一个线段树即可;求每个位置的,可参考树状数组求逆序数的思路原创 2017-07-31 18:51:42 · 320 阅读 · 0 评论 -
Treap
二叉平衡搜索树的一种实现形式,在键值满足二叉搜索树的前提下,增加了priority满足堆序的条件,即为了实现二叉搜索树的平衡化,才增加了堆序的性质,可以证明,如果priority是随机的,那么treap的期望深度是O(logN)的,也就是大部分操作可在O(logN)的时间内完成。 背景: 可以证明,如果一个二叉排序树节点插入的顺序是随机的,这样我们得到的二叉排序树大多数情况下是平衡的,即使存在原创 2017-07-21 01:01:02 · 688 阅读 · 0 评论 -
POJ 3667 Hotel(线段树区间合并查询)
题目链接:点击打开链接 题意: 1 a:询问是否有连续长度为a的空房间,有的话选最左边 2 a b:将[a,a+b-1]区间的房间清空 思路:这类题目会询问区间中满足条件的连续最长区间,所以pushUp的时候需要对左右儿子的区间进行合并;用lsum,rsum,msum三个数组记录区间中最长的空房间 // POJ 3667 Hotel.cpp 运行/限制:1079ms/3000ms #in原创 2017-08-01 12:04:28 · 302 阅读 · 0 评论 -
Splay树(伸展树)
伸展树(Splay Tree),是一种二叉平衡搜索树,时间复杂度均摊为O(logN),即splay树做m次操作的复杂度为O(mlogN)。 在伸展树上的一般操作都基于伸展操作/提根操作: 假设想要对一个二叉搜索树执行一系列的查找操作,为了使整个查找时间更小,被查频率高的那些条目就应当经常处于靠近树根的位置。于是想到设计一个简单方法, 在每次查找之后对树进行重构,把被查找的条目搬移到离树根近原创 2017-07-23 11:46:40 · 1093 阅读 · 0 评论 -
HDU 1542 Atlantis(矩形面积并,线段树+离散化+线扫描)
题目链接:点击打开链接 题意:矩形面积并 思路:由于数据较大,浮点数先要离散化;然后把矩形分成两类边,上边和下边,相关信息存到结构体中;对离散化后的横轴建线段树,然后对于每条边,自下而上扫描上去,每次扫描到的块为当前边与下一条边之间的块,sum代表区间内被覆盖的线段的长度总和,那么sum[1]就表示当前块 线段(横轴)的总长度,每次处理用sum[1] * 当前块height就是该块面积;这原创 2017-08-01 17:45:02 · 383 阅读 · 0 评论 -
POJ 2528 Mayor's posters(线段树+离散化)
题目链接:点击打开链接 题意:在墙上贴海报,海报可以相互重叠,问最后可以看到几张海报 思路:可以采用线段树,按照贴海报的顺序去更新线段树染色,最后查询整个区间的染色数即为所求;但是数据太大,所以需要离散化。 离散化简单的来说就是只取我们需要的值来用,复杂度就大大的降下来了。离散化要保存所有需要用到的值,排序后,分别映射到1~n,这样复杂度就会小很多很多 而这题的难点在于每个数字其实表示的是原创 2017-07-31 23:40:13 · 342 阅读 · 0 评论 -
2017百度之星资格赛 1002 度度熊的王国战略(并查集 or 无向图最小割)
题目链接:点击打开链接 题意很容易理解,基本上这个题意就是让你去考虑无向图的最小割,无奈只会用模版,还没想好怎么用堆优化Stoer-Wagner算法,TLE......而且百度把这题的时间放宽到了2000ms,这样还超时,不会优化真尴尬......SW算法用堆优化一般适用于稀疏图,如果是稠密图,优化还可能更费时,看此题的数据,点的个数取值为3 * 10^3,边的个数为10^5,应该是稀疏图的测试原创 2017-08-07 00:25:39 · 1032 阅读 · 0 评论 -
Wannafly挑战赛1 MMset2(虚树+树的直径)
题目链接:点击打开链接 思路:虚树直径除以2,向上取整。不会证明的话,仔细思考、举几个sample可以YY出来。 通过这个题学了几个新东西: 1.虚树 所谓虚树,其实就是把询问中需要用到的点建到另一棵树上,对于一些问题可以降低复杂度。比如我们询问一条链上的两个端点,直接做dfs的复杂度是O(N)的,但是对于虚树,这两个端点可以直接相连,它们之间的边记录了原本整条链上的信息,于是复杂度变成了原创 2017-10-17 16:42:53 · 596 阅读 · 0 评论 -
HDU 1512 Monkey King(左偏树)
题目链接:点击打开链接 题意:一群猴子,每个猴子均在唯一的一个组里,可单独成组。当两个猴子要打架时,若在同一组,不可以打架,若不在一组,每个猴子找到本组中最强壮的去迎战,打完架的两个猴子,强壮值减半,而且这两组猴子合并为一组。 由最强壮的猴子迎战,而且要合并组,可以想到左偏树(有合并操作的堆)。不同于简单的左偏树模板的是,由于要尽快的找到某个节点的堆顶,借助于并查集的思路,存每个节点的父亲节点原创 2017-07-16 14:05:32 · 439 阅读 · 0 评论 -
POJ 2001 Shortest Prefixes(字典树)
题目链接:点击打开链接 题目大意很简单,就是给出一组字符串,给出能唯一确定每个字符串的前缀。首先进行插入操作建树,然后对每个字符串,再去查询,查询的过程中,遇到出现一次的前缀即为所求 // POJ 2001 Shortest Prefixes.cpp #include #include #include #include #include using namespace std; s原创 2017-07-15 18:07:17 · 312 阅读 · 0 评论 -
Poj 2236 Wireless NetWork(并查集)
An earthquake takes place in Southeast Asia. The ACM (Asia Cooperated Medical team) have set up a wireless network with the lap computers, but an unexpected aftershock attacked, all computers in the n原创 2017-03-27 19:51:54 · 568 阅读 · 0 评论 -
HDU 1754 I Hate It(线段树 单点替换,区间最值)
链接:点击打开链接 #include #include #include #include #define MAXN 200005 using namespace std; int tree[MAXN<<2]; void PushUp(int root){ tree[root]=max(tree[root<<1],tree[root<<1|1]); } void BuildTree(i原创 2016-12-10 16:59:55 · 374 阅读 · 0 评论 -
山东省第六届ACM竞赛 山东理工SDUT3258 Square Number
Problem Description In mathematics, a square number is an integer that is the square of an integer. In other words, it is the product of some integer with itself. For example, 9 is a square number,原创 2017-04-30 17:05:04 · 802 阅读 · 0 评论 -
HDU 1556(树状数组 区域更新,单点求值)
链接:点击打开链接 //区域更新,单点求值的函数 同 单点更新,区域求值 //但主函数处理不同 至于为何? #include #include #include using namespace std; #define MAXN 100001 int tree[MAXN]; int n; int LowBit(int t){ return t&(-t); } voi原创 2016-12-04 18:43:35 · 508 阅读 · 0 评论 -
树状数组
转自:点击打开链接 树状数组 (1)、单点增减+区间求和 思路:C[x]表示该点的元素:sum(x)=C[1]+C[2]+……C[x] [cpp] view plain copy print? int arr[MAXN]; inline int sum(int x){int res=0;while(x)res+=arr[x],x-=lowbi转载 2016-12-04 18:33:32 · 347 阅读 · 0 评论 -
HDU 1166(树状数组 单点更新 区域求值)
链接:点击打开链接 #include #include #include using namespace std; #define MAXN 50005 int tree[MAXN],n; int LowBit(int position){ return position&(-position); } void Add(int position,int value){ for(int原创 2016-12-04 17:35:58 · 441 阅读 · 0 评论 -
HDU 1698(线段树 区域更新,区域求值)
题目链接:点击打开链接 //区域更新 区域查询 //需要用到延迟标记(或者说懒惰标记),简单来说就是每次更新的时候不要更新到底,用延迟标记使得更新延迟到下次需要更新or询问到的时候 //PushDown()需要认真想明白; //大体意思是: //每次查询到(L,R)大于(l,r)的区间,先把此段更新(或是替换原来的col),然后回溯,更新(PushUp)父节点们 //不先去管子节点们,反正已经此原创 2016-12-04 15:38:30 · 391 阅读 · 0 评论 -
HDU 1166(线段树 单点更新 区域求值)
题目链接:点击打开链接 代码:自己 //单点更新 区间查询 #include #include #include using namespace std; #define MAXN 50005 int setTree[MAXN<<2]; void PushUp(int root){ setTree[root]=setTree[root<<1]+setTree[root<<1|1];原创 2016-12-04 11:43:23 · 320 阅读 · 0 评论 -
线段树
线段树 转载自:http://blog.csdn.net/metalseed/article/details/8039326 一:线段树基本概念 1:概述 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,它基本能保持每个操作的复杂度为O(lgN)! 性质转载 2016-12-04 10:18:08 · 534 阅读 · 0 评论 -
二叉树
ACM竞赛不常用,PAT倒是常用到 大体两种实现方式:指针,数组 指针实现,有利于理解数据结构的内在和提高能力,但竞赛实用性差,竞赛常用数组实现 数据结构学习时应该用指针实现,具体应用时用数组较好 指针实现:大概就是先记录数据和左右孩子编号,再去递归建树或者层序建树(层序用队列实现),具体实现略 数组实现: 用三个数组,数组长度为节点最大个数。data[N],left[N],right原创 2017-07-12 22:23:09 · 316 阅读 · 0 评论 -
二叉搜索树
二叉搜索树可进行查询,插入,删除操作,不是平衡树,平均时间复杂度O(logN),还可到达O(N) ACM竞赛也不大常用二叉搜索树,PAT还是常考 实现方法:指针和数组 指针:除了数据结构学习时,竞赛很少用到指针实现 法一:基于C++类封装实现 #include "stdafx.h" #include #include #include #include #include us原创 2017-07-13 00:37:05 · 302 阅读 · 0 评论 -
二叉堆
二叉堆是完全二叉树,实现 查询最值,插入元素,删除任意元素(堆顶或其他),修改任意元素值 的功能,复杂度为O(logN) 由于是完全二叉树,所以用数组实现,方便快捷 法一:普通实现 //Binary Heap,the most common implement of Poriority Queen(Heap) //以最小堆为例 #include #include原创 2017-07-13 20:55:40 · 556 阅读 · 0 评论 -
HDU 1873 看病排队(优先队列)
此题水题,价值不大。写这个题解,是想回顾一个问题:变量的生命周期问题,C语言基础中的基础...... #include #include #include #include #include #include using namespace std; struct node { int index, prior; node(int a, int b) :index(a), pr原创 2017-07-15 01:26:46 · 532 阅读 · 0 评论 -
并查集的写法
法一: int fa[MAXN+1]; void Init(int n){ for(int i=1;i<=n;i++){ fa[i]=i; } } int GetFather(int x){ return fa[x]=(fa[x]==x?x:GetFather(fa[x])); } void Merge(int x,int y){ int a=Get(x); int b=Get(y原创 2017-03-27 20:15:51 · 1020 阅读 · 0 评论 -
POJ 1611 The Suspects(并查集)
题目链接:点击打开链接 简单的并查集,水题 // POJ 1611 The Suspects.cpp #include #include #include #include using namespace std; class DisjointSet { private: int n; vector fa, rank; public: DisjointSet(int n) :n(原创 2017-07-15 15:45:56 · 391 阅读 · 0 评论 -
Wannafly模拟赛3 监视任务(贪心+线段树)
题目链接:点击打开链接 思路:把所有约束按照右端点排序。这样每一个前面的约束区间[l1,r1],与后面的一个约束区间[l2,r2]的交,一定为[max(l1 ,l2 ),r1]。对于排序后的区间依次满足约束,假设当前枚举到的约束还没有满足,就不断把对应区间中最右端的0改为1,这些过程可以用线段树维护来完成。时间复杂度O((n + m)logn)。 // 监视任务 运行/限制:898ms/200原创 2017-10-14 22:42:17 · 362 阅读 · 0 评论