随笔分类 - 数据结构
摘要:树题意:给一个有向图,判断是否为有根数树这题应该来讲是个水题但是OJ将其归为星题,主要是容易WA,理清逻辑就可以了注意:有根树的判定,1.连通,2边数+1 = 点数 3.无环 由两个可以推到另一个做这题紧紧抓住树的定义即可,另外处理一下下面的一些特殊情况1.题意要求是树,不能是森林2.空树也是树,题目一开始说了3.数据中可能有自环,即1 1这种,这样就不是一棵树了3.有重边,1 2 , 1 2,同样不是树4.有环,1 2 , 2 1,同样不是树5.横叉边 2 3 , 4 3 , 同样不是树网上都说并查集,其实不用那么麻烦,就模拟一下即可#include <iostream>#inc
阅读全文
摘要:LCA题意:LCA模板题,输入n和m,表示n个点m条边,下面m行是边的信息,两端点和权,后面的那个字母无视掉,没用的。接着k,下面k个询问lca,输出即可有人说要考虑不连通的情况,我没考虑AC了,另外可能有u,u这样的询问,不过这不影响,照样是写模板,没有特判,一样能过还是Tarjan快一些LCA转RMQ在线算法#include <iostream>#include <cstdio>#include <cstring>#include <cmath>using namespace std;#define N 40010#define M 25in
阅读全文
摘要:LCA模板题题意:给一个无根树,有q个询问,每个询问两个点,问两点的距离。求出 lca = LCA(X,Y) , 然后 dir[x] + dir[y] - 2 * dir[lca]dir[u]表示点u到树根的距离下面两份代码都可以通过HDU的C++和G++,都不存在爆栈问题,网上很多人说会爆栈,加了申请系统栈语句,其实不用,而且好想比赛中不允许使用的Tarjan算法跑得更快些,C++ 15ms, G++ 50ms 左右, RMQ大概60ms在线算法:LCA转化为RMQ#include <iostream>#include <cstdio>#include <cst
阅读全文
摘要:LCA题意:给一个无根树,有q个询问,每个询问3个点,问将这3个点连起来,距离最短是多少,LCA的模板题,分别求LCA(X,Y),LCA(X,Z),LCA(Y,Z),和对应的距离,然后3个距离相加再除以2就是这个询问的结果对于一对点,x,y, lca = LCA(x,y) , 那么点x到点y的距离为 dir[x] + dir[y] - 2 * dir[lca] ; 其中dir[u] 表示点u到树根的距离由于是模板题,只给代码,详细的讲解可以在学习笔记里面找《LCA与RMQ》在线算法:LCA转RMQ#include <iostream>#include <cstdio>#
阅读全文
摘要:线段树 + DP题意:一个游戏(做题前可以先玩一下帮助理解)。题意比游戏简易:每个木板都有一个权值,可正可负或0,人在上面,自身能量要加上这个权值(即能量会发生增减)。人一开始有100能量,站在最高的木板上(要加上这个能量的权,所以其实起始能量应该为100+该板能量)。然后人往下跳,跳法有讲究并不像真实游戏那样可以移动,人下落,只能从一块木板的端点垂直下落,中途不能移动,这和实际游戏有区别,但是也使问题简化了。问这个人怎么跳,使在它落到地面的时候,能量最大,如果中途或者到地面能量<=0,或者跳到一个木板上,下面没有木板可以接住自己了,那么游戏结束,输出-1分析:既然只能垂直下落,而且是落
阅读全文
摘要:线段树题意:1到n的线段,m个操作Reset 将所有内存清空New x 申请一段长度为x的最左的未被占用的区间,返回它的位置,并占用它。找不到输出Reject NewFree x 找到x单元内存所在的连续的单元块,返回这个单元块的左右端点,并且清空这个单元块,如果这个单元x根本没被占用,则输出Reject FreeGet x 找到第x个单元块(而不是第x单元),返回这个单元块的起始位置即左端点这题还是和 poj 3667 Hotel 是一样的,查询一个最左的合法区间,修改一段区间这题使用vector按顺序来保存单元块,方便查找(可以使用二分)而线段树主要的query和updata函数是一样的#
阅读全文
摘要:线段树题意:一个长度为n的线段,下面m个操作D x 表示将单元x毁掉R 表示修复最后毁坏的那个单元Q x 询问这个单元以及它周围有多少个连续的单元,如果它本身已经被毁坏了就是0要记录单元被损坏的顺序,用一个栈就好了,毁坏就入栈,修复就出栈说说思路,最难的是查询一个点附近有那些的连接着的区间这需要在线段树记录三个信息,tlen,llen,rlen,这个记录和poj 3667 Hotel记录的意义是相同的 , tlen表示该节点内最长的可用区间的长度,llen表示最左端数起的区间长度,rlen表示从最右端数起的区间长度对于一个点,看它是在当前区间的左半还是右半在左半的话,看看是不是在右端的连续区间
阅读全文
摘要:推荐技术公众号:不爱睡觉的大猪 线段树 题意:有一个线段,从1到n,下面m个操作,操作分两个类型,以1开头的是查询操作,以2开头的是更新操作 1 w 表示在总区间内查询一个长度为w的可用区间,并且要最靠左,能找到的话返回这个区间的左端点并占用了这个区间,找不到返回0 好像n=10 , 1 3 查到的
阅读全文
摘要:数据结构--二叉查找树遍历题意:n,表示二叉查找树的节点个数,每个节点有个数值,并且数值各异不会出现重复的,查找树左子树的节点数值小于根,右子树的节点数值大于根。 一般的后序遍历二叉树时 左孩子,右孩子,根 ; 现在定义一种新的后序遍历 右孩子,左孩子,根 输入n,下面一个序列,是普通后序遍历二叉树的序列 , 要你根据这个序列,输出新定义的那种后序遍历序列 讲到这里,看图,看sample可以理解题意了要是一般的二叉树只知道后序遍历序列是不能建树的,但是这里是二叉查找树却可以对于一个后序遍历序列,它可以分解为 (左子树部分)(右子树部分)(根),由于是查找树,可知(左子树)<(...
阅读全文
摘要:线段树题意:有一个长H宽W的板,上面贴纸条,纸条都是长1宽w的,贴纸条的原则是,不能覆盖或重叠别人的纸条,尽量往上贴,进而尽量往左贴第一行3个数字,H,W,N,N表示有N个纸条,下面n行每行一个数字,表示每个纸条的宽,每个输入对应一个输出,就是这个纸条放在哪一行,如果没地方放它就输出-1数据很大,不过是纸老虎,因为H=min(H,N),这个很容易理解,行数多了也用不上。/*h=min(h,Q);线段树区间长度为h,每个叶子a[i]表示第i行剩下的长度,一开始都是w对于每个询问,我们其实是将长度为l的长条放入一行呢,即对应放到a数组的一位里,要满足a[i]>=l,并且最靠左所以问题转化为在
阅读全文
摘要:线段树求面积并升级版题意中文,不解释这题的代码在一般的线段树求面积并的基础上进行了修改,但是所用的思想是一样的,所以不难理解回忆一下一般的求矩形覆盖面积,线段树节点里面有一个重要的变量,cnt。这个变量表示了该节点表示的区间被完全覆盖,如果cnt=0,说明没有被完全覆盖(但不代表没有被覆盖),要算出该节点所代表的区间被覆盖的长度,需要由它左右孩子节点被覆盖的长度相加所得。如果cnt=1,表示被完全覆盖,覆盖长度就是该区间长度。如果cnt>1说明也是被完全覆盖,不过不止覆盖了一次,在算覆盖长度的时候,和cnt=1的计算方法是一样的。注意一点,节点里还有另一个变量len,就是该区间被覆盖的长
阅读全文
摘要:两种方法详细分析:线段树辅助——扫描线法计算矩形周长并(轮廓线)第一种,对横线和竖线做相同的操作/*对横线和竖线做两次一样的操作这题不需要离散化*/#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define N 5010#define MAX 10010#define lch(i) ((i)<<1)#define rch(i) ((i)<<1|1)int res;struct segment{ int l,r,h,v;}sx[2*
阅读全文
摘要:数据结构:暴力(可用哈希优化)+建树+前序遍历题意:输入行数n,下面n行是一下文件的路径(和平常使用的电脑一样),一整行数据中没有空格(还好,别有搞些空格出来),要你整理好所有文件的路径,从根开始,输出所有的文件夹名首先一点,我们要名字,在同一个文件夹下,是不会有重名的文件夹的即a\ba\b这种是非法的(和电脑一样),但是输入中可以有,有的话只是一种重复输入,不是代表a下面真的有两个b然后不同文件夹下可以由相同的名字,就好比你D盘和E盘都有一个文件夹叫“电影”例如a\bd\b这种是合法的在输入中也是会出现的,看case就知道。另外,每个文件夹都只有一个双亲好像a\b\c\d , 你要找d,输入
阅读全文
摘要:数据结构:堆题目请你写一个内存管理系统。 内存中有30000个块,编号为1..30000。 当操作系统需要内存时内存管理系统会找出编号最小的空闲块,向里面写入数据。 操作系统还会会发出指令读取某个编号的内存块。如果目标块空闲,读取失败,否则读取成功。 一开始所有块都是空闲块。被写入数据之后就不是空闲块了。 如果一个块在600秒内没有被写入或读取,这块内存自动清空,变为空闲块。 本题中不会出现内存块不够用的情况。输入格式每行一个要求,可能是申请内存或读取。申请内存的格式如下: T + T表示这条请求收到时的时间,是不大于65000的整数,以秒为单位。读取内存的格式如下: T . N T表示这条请
阅读全文
摘要:树状数组题意:一个树,以树枝连接两个点的形式给出,固定以1为整棵树的根。苹果长在树的节点上,节点上只可能0或1个苹果,一开始每个节点都有1个苹果有两种操作,C表示更改某个节点的苹果数,0变1,1变0。Q表示查询,某个节点(包括)的子树上一共有多少个苹果这题是选拔赛时候的题,一看,单点修改,区间查询?线段树?后来一直没想出来,今天看解题报告才明白真的是,不过是树状数组(不过按照理论来将,凡是树状数组能解决的问题,线段树都可以解决,反之不然)。整个问题最难的时候怎么映射成树状数组,映射后,只是树状数组的模板操作1.首先数据太大,不用显式建树,只是用vector来保存边的信息,仅仅是利用vector
阅读全文
摘要:线段树题意:很明显的线段树。做了这题更加让我注意了用点和用段来建树的区别。这题是用点来表示线段的。一开始从0到10^9这个点之间的线段都是白色的,然后m个更新,每个更新 a,b,col,表示从点a到点b这条线段染成黑色或白色,问最后,白色线段中最长的是哪一段,输出它的位置(即线段两端的端点)注意更新的时候a,b的数值范围是 0<a<b<10^9 , 其实这样给数据方便了处理,否则的话最后要搞一下挺烦的先看看用段和用点表示线段树的区别。用点的话,0,1,表示的长度是1。1,3表示的长度是2。而用段的话1,3表示的长度是3,就是这个意思线段树的建树,无论在何种情况下,应该说建树的
阅读全文
摘要:并查集题意:题意比较好懂简单说一下。一个序列,只有0,1;输入n,表示序列长度(从1到n标号),输入m,下面m个更新,每行都是a,b,string,表示说序列中下标a到下标b的元素中有偶数个或奇数个1.没得到一个更新就更新序列的信息,知道读入第k个信息,和已建立的信息矛盾,那么结束,输出k-1,表示前面k-1个更新不矛盾,如果m个更新都成立,那么输出m这题要转化一下,一转化就比较明显了。我们定义前缀和为sum[i]表示1到i的和,那么sum[b]-sum[a-1]=c[a]+c[a+1]+c[a+2]……c[b] , 即序列的[a,b]区间和因为序列中只有0,1所以区间和的奇偶性就是该区间拥有
阅读全文
摘要:线段树求体积并题意来自网上,懒得写了。。。。有一块田,上面有n个矩阵,每个矩阵对应一个权值,矩阵相交的部分取权值大的,问最后能获得多少值我们可以转换一下模型,将权值看成矩阵的高,那么题目就成了n个长方体求并,由于m只有3,所以我们可以枚举高度,在每个高度用扫描线做一次矩阵面积并,最后求和即可,最多只有3次扫描线(想象一下长方体,交错在一次,有高有低,怎么求出整个立体形的体积)注意一点,这题数据还是比较大的,用int很危险,不旦最终答案要__int64,中间的一些乘法是会溢出的,我就是用int,WA了好几次,后来把所有改为__int64就过了#include <cstdio>#inc
阅读全文
摘要:并查集选拔赛的题目。题意:如图所示是一些六边形的单元,一开始初始化所有的单元都是海洋,然后给你一个序列,就是一个单元坐标的序列。如果这个单元是个海洋,看能不能把它变成陆地,能变成陆地的条件是,如果它周围(也就是和它直接相连的那六个单元)已经是陆地,加入这块会使总陆地面积变大,但是面积有个限制值s,一块陆地的总面积不能超过s,如果加入这块不超过限制那么就加入,并且这个块海洋变成了陆地,如果超过了限制值那么这块单元要忽略,依然是海洋。如果是这块单元已经是陆地了,那么直接跳过。一整块陆地的总面积就是它拥有的单元数要你输出最后有多少块大陆地,每一块的面积是多少,面积按升序输出这里要注意,好像(1,1)
阅读全文
摘要:线段树一样的题目http://www.cnblogs.com/scau20110726/archive/2013/02/24/2923923.html
阅读全文