线段树&树状数组
文章平均质量分 86
Dan__ge
Today is difficult,tomorrow is more difficult,but the day after is beautiful.
展开
-
51nod 1672 线段树
点击打开链接题意:中文思路:本弱并不会,看了看出题人的题解,总是感觉被智商压制了,首先要按左端点排序,然后右端点的位置在线段树中更新+1,然后对于每一个区间来说,以这个区间的左端点为开始,那么我们就要找一个最远的右端点且被覆盖过K次的那个点,这就要在查询时来完成这个要求了,与其说是算法还不如说是想法题#include #include #include #include #incl原创 2016-10-19 15:33:08 · 446 阅读 · 0 评论 -
HDU 3584 树状数组
点击打开链接题意:三维的空间中有两个操作,初始时每个空间元素均为0,然后更新操作是0变1,1变0,是一个空间内的所有元素都更新,然后查询是问这个点的元素是0还是1思路:因为不好去更新到每一个点,那么我们可以统计空间的翻转的次数,然后用三维的树状数组即可,但是更新时不能只更新那个点,因为如果这样能的话,能够包括这个区间的大区间因为还没有更新过而和变成了1,那不是我们要的,所以我们将包围这个区原创 2016-06-30 20:03:13 · 2039 阅读 · 2 评论 -
HDU 2642 树状数组
点击打开链接题意:给个二维矩阵,矩阵有0或者1两个值,然后有三个操作,Q问区间和,剩下两个是更新点的值思路:更新点的值直接更新就行了,然后询问区间和的时候就处理一下,每次问的是X1,Y1到X2,Y2的区间和,而树状数组的和是从1,1开始的,所以总的减去多于的在加上多减去的就OK了#include #include #include #include #include using原创 2016-06-30 19:45:35 · 1678 阅读 · 0 评论 -
HDU 3473 划分树
点击打开链接题意:问你给定区间的给出的表达式的最小值思路:看了网上题解,都说中位数便是最优的解,证明不会,那么跟着思路做就行了,用划分树找出中位数然后在划分树中加入区间的前缀和即可,加的时候只要查询的值走到右子树那么就加起来,因为它向右走了,那么左边全是比它小的要加起来,小于它的个数一样统计一下即可,然后有了这两个推个小公式就行了#include #include #include原创 2016-06-14 21:28:38 · 1710 阅读 · 0 评论 -
HDU 3465 线段树
点击打开链接题意:给了n条直线,问你在开区间L到R中有多少对直线的交点思路:大神们的智商不是我等可以理解的(/ □ \),那么怎么写呢,看一看线段相交的充分条件,(x1-x2)*(y1-y2)#include #include #include #include #include using namespace std;typedef long long ll;typ原创 2016-06-13 20:08:14 · 1722 阅读 · 0 评论 -
HDU 3577 线段树区间更新
点击打开链接题意:一辆火车,同一时间最多可以坐K个人,然后n个人依次买票,上车时间为a,下车时间为b,问这个人能不能上去,最后将所有的可以上车的人输出思路:将所有的时间看成区间,然后对于a到b,询问这段中被覆盖的最大次数,若不超过K,说明这个人可以上这段,然后更新就好了#include #include #include #include #include using names原创 2016-06-29 16:18:32 · 1626 阅读 · 0 评论 -
HDU 3564 线段树+简单DP
点击打开链接题意:N个数从1到N,按照顺序插入到这N个位置,然后每插完一个求LIS思路:不可能插一个求一次,换个想法先将每个点在序列中的位置求出来,然后在位置的基础上求LIS就可以了,因为插入的时候当前插入的这个点肯定是最大的,所以位置当成数值求LIS就是正确的#include #include #include #include #include using names原创 2016-06-29 14:18:03 · 1448 阅读 · 0 评论 -
HDU 4630 线段树+离线处理
点击打开链接题意:给一串数字序列,然后问你L到R中的两个数的最大公约数最大,若相等的两个数则是0思路:又是一道需要离线处理的题目,昨天写的HDU 3333也是一道这样的题目,建议先写3333在写这个会有帮助,那么对于这个序列我的每一次提问L到R那么最大的是多少,我们可以这样考虑,这区间所有的数的因子的个数大于等于2就可以竞争这个最大的提问,然后选出最大的即可,那么对于R来说,R的所有因子上原创 2016-06-13 14:58:07 · 931 阅读 · 0 评论 -
HDU 3333 线段树+离线处理
点击打开链接题意:问你给定区间内的不重复的数字的和,如1 1 1 3 4 ,区间1到2就是1,区间1到5就是8思路:这种线段树只能离线来写,离线的方法是按照查询区间的右端点来排序,然后这道题目的数据范围较大需要离散化简单处理一下,然后对于输入的每个点来说,顺序走下去,然后如果当前点之前出现过,便将之前的删除然后把现在的添加线段树中,为什么这么可以,看了网上神犇一句话,那就是对于要查询的区间原创 2016-06-12 21:03:43 · 2984 阅读 · 0 评论 -
ZOJ 3772 线段树
点击打开链接题意:给一个数字序列,然后有m次询问,每次询问给了一个递推关系,然后输出询问的R的值思路:n是100000,m是100000,然后来询问,就算不知道题意肯定也要向线段树这方面来想,而线段树的应用无非就是节点保存的信息嘛,这道题目要的是一段连续的递推式子,那么我们的节点就可以保存递推式,而这个式子也很好推,看代码应该可以看得懂,然后飞根节点保存的就是两个儿子的矩阵乘积后的矩阵,然原创 2016-05-23 20:20:48 · 4461 阅读 · 0 评论 -
HDU 5493 线段树
点击打开链接题意:给n个人的身高和一个k,k代表的是这个人前边比他高的人的数量或者是后面的比他高的人的数量,问能否将这n个人满足条件的排序,有多解时输出字典序最小的思路:看到100000个人,感觉是线段树,但是没什么思路,看了大神们的博客,发现只要转化一下便是简单的线段树模型了,对于每个人来说,k就是前边留k个位置,后者后边留k个位置,当然这两个我肯定要选的是小的那个位置,这要是为原创 2016-05-23 17:18:49 · 3316 阅读 · 0 评论 -
HDU 3607 线段树
点击打开链接题意:个n个点的高度以及点上的金子数,现在从1开始走到n,要求每走一步高度要严格递增,且只能向右走,问最多可以捡到多少金子思路:这种题看起来像是dp,因为求最多什么的嘛,但是其实用线段树就可以求解,然后数据范围过大我们需要离散化一下,然后遍历每一个点,找到它的排名,然后询问1到它的排名下一位的最大值,加上它自己的金子就是走到这的最多可以获得的,然后更新这个点的金子数,依次下去到原创 2016-07-14 16:49:03 · 1248 阅读 · 0 评论 -
HDU 5316 线段树区间合并
点击打开链接题意:对数字序列有两个操作,1是将值修改,而0是询问a到b的最大值,最大值定义为所选的相邻的数的下标一个为偶数一个为奇数思路:肯定是线段树的题目,因为有这样的限制条件那么会用到线段树的区间合并,而这道题我们可以找最大值的情况很多,1可以是奇数开头奇数结束的,2可以是奇数开头偶数结束的,3可以是偶数开头奇数结束的,4可以是偶数开头偶数结束的,所以我们最后的最大值也要在这四个里面选原创 2016-07-04 19:38:52 · 2065 阅读 · 0 评论 -
HDU 4302 线段树
点击打开链接题意:在一个0到L的坐标上,0是在某个位置摆个蛋糕,然后1是吃蛋糕,但是吃的必须是离自己最近的,若没有蛋糕就不动,若有两个蛋糕与其距离相等,那么我们选择上一步的方向来吃蛋糕,问最后这个人走了多远思路:用两个队列应该就可以很简单的完成,但是想到了线段树,就写个线段树,而线段树一样维护的是最大值和最小值,不过这两个值都是对应的位置,那么对于队列来说肯定就是也维护这两个值,然后讨论处原创 2016-07-15 13:22:44 · 937 阅读 · 0 评论 -
51nod 1208&& POJ 2482
51nod点击打开链接题意:中文思路:将二维转化成一维来做,对于当前点来说它可以产生结果的区间是Y到Y+H,然后停止产生结果是在X+W+1处,所以在X+W处标记一下即可,用线段树边扫描边更新最大值#include #include #include #include #include using namespace std;typedef long long ll;typed原创 2016-10-19 14:09:47 · 470 阅读 · 0 评论 -
51nod 1685 树状数组+打标记
点击打开链接题意:中文思路:之前看了好久感觉应该二分答案,但是二分条件不会写,看了出题人的题解恍然大悟,对于二分的mid,统计到i为止的大于等于mid的个数,然后若一段区间的中位数大于等于mid的话,则2*(num[r]-num[l-1]>r-l+1;代表这个区间的大于等于mid的个数比区间一半的元素多,则中位数就大于等于md,转化一下就是2*num[r]-r>2*num[l-1]-l+1原创 2016-10-27 13:06:49 · 493 阅读 · 0 评论 -
HDU 3397 线段树区间合并
点击打开链接题意:五种操作,0全部置0,1全部置1,2是0变1 1变0,3是询问1的个数,4是询问最长连续的1思路:推荐先写hdu 3911 ,是这题的简单版,这题注意的地方就是一旦有置0和置1操作,那么2操作的标记就要被覆盖,剩下的操作都是比较精典的区间合并操作了#include #include #include #include #include using namespa原创 2016-09-30 17:36:57 · 399 阅读 · 0 评论 -
51nod 1766 线段树维护树的直径
点击打开链接题意:中文思路:用线段树维护树的直径,具体的可以参考这篇文章,首先要知道如何合并一个区间,那么要知道左区间的最长路径的两个端点以及右区间的两个端点,合并后的最长路径就是4个端点的6种组合中的一个,知道这个就相对简单点了,路径长度的计算可以用LCA-RMQ来完成#include #include #include #include #include #include原创 2016-10-26 13:47:41 · 632 阅读 · 0 评论 -
HDU 3911 线段树区间合并+异或操作
点击打开链接题意:给一个长度为n的由0和1组成的一个数列,操作0是询问a到b的最长连续的1的个数,操作1是将a到b序列里的是异或,即0变为1,1变为0思路:如果没有异或的操作,就是直接简单的区间合并记录每个区间的从左开始的1的连续个数和从右开始的1的连续个数即可,而多了异或操作,可以在记录一个从左从右开始的0的个数就可以了,异或时直接交换这两个值即可#include #include原创 2016-09-29 16:00:55 · 549 阅读 · 0 评论 -
SPOJ 3267 主席树||线段树+离线
点击打开链接题意:给一个数列,然后多次询问,询问l到r区间内不同数字的个数思路:主席树模版题目或者线段树+离线操作都可以,而线段树+离线的话HDU 3333 也是一道基础的题目,求得是不同数字的和,变成个数就是这道题目了先是主席树的,代码参考kuangbin巨巨#include #include #include #include #include #include #in原创 2016-10-13 14:17:15 · 493 阅读 · 0 评论 -
POJ 3667 线段树区间合并
点击打开链接题意:给n个连续的房间,然后1是询问有没有连续的b房间,没有输出0,有输出满足的最小的房间号,2是b到b+c-1的房间空出来了思路:就是线段树区间合并维护最大连续空房间即可,加两个辅助数组L和R分别代表从左开始的最大连续和从右开始的最大连续,pushup时处理就行了#include #include #include #include #include using n原创 2016-09-19 18:49:58 · 331 阅读 · 0 评论 -
HDU 5023 线段树
点击打开链接题意:一段序列,有两个操作,一个是将a到b涂成c颜色,一个是询问a到b的颜色种类输出思路:这道题目就是简单的线段树变形,但是要注意它要的是区间所有颜色,队友机智的先到线段树做位运算便可以将所有的颜色都得到,因为c最大是30,那么我们可以将颜色定义为一个二进制的第c-1位是1,其余为0,线段树的成段更新也是这样,然后做或运算,就可以将所有的颜色得到了 PS:刚开始我还没想到原创 2016-08-08 20:24:24 · 372 阅读 · 0 评论 -
HDU 5029 树链剖分
点击打开链接题意:给一个树,然后操作是将颜色z涂在u到v路径上的所有点,最后问你每一个点上哪个颜色涂的最多,若有多组解,输出颜色较小的那个思路:因为是在树上的更新操作,所以需要用树链剖分来将树形的结构简化成线性的结构,从而使用线段树来更新,然后用类似离线的方法,现在规定对于U到V的路径上,它投影到线性结构的起点和终点是S和T,那么对于z来说它可以作用的范围就是S到T,此时我们维护的线段树的原创 2016-08-08 20:14:49 · 471 阅读 · 0 评论 -
HDU 5372 线段树
点击打开链接题意:两个操作,0是添加一段线段,然后问添加的这段线段完全覆盖之前的多少个线段,然后0是将第b个添加的线段删除思路:对于一个当前添加的线段来说,它能完全覆盖的线段个数就等于大于等于这个线段的左端的数量减去大于右端点的线段数量,因为题目中有个至关重要的条件那就是每次添加的线段的长度是越来越大的,那么对于之前的线段只有大于等于左端点的才可以,这么说吧,之前的线段的左端点比当前小的,原创 2016-07-08 17:29:50 · 1508 阅读 · 0 评论 -
HDU 3450 线段树+二分
点击打开链接题意:给一个数字序列,问你长度大于2的且相邻两个数的差的绝对值不大于d的情况对9901取余思路:看了根本不会,都没想到是线段树的题目,弱哭~~~,看了大牛们的题解,算是知道怎么回事了,对于当前的数A,那么以它为最后一个元素可以组成的情况是A-d到A+d的和,也可以这样想,A-d的已经组成了m种情况,那么在不影响小于d的情况下,可以直接将A放到A-d组成的左右序列中,那么直接加就原创 2016-06-09 11:03:24 · 2466 阅读 · 0 评论 -
HDU 4819 二维线段树
点击打开链接题意:求区间的最大值与最小值的差和单点更新思路:二维线段树的模版直接用就行,更新就是先找到x所在的区间然后再找y所在的区间,与一维的十分类似,看代码应该可以看懂吧~~~(/ □ \)#include #include #include #include #include using namespace std;typedef long long ll;const原创 2016-06-25 13:37:09 · 1891 阅读 · 0 评论 -
coderforces 138CMushroom Gnomes - 2线段树
点击打开链接题意:给定n个树,和m个人,接下来n行是每个树的位置,高度,向左倒的概率,向右倒的概率,接下来给出m个人的位置,判断每个人活下来的概率乘上Zi然后相加。思路:涌用线段树的节点维护概率,先进行离散化,本来的话可能应该用到成段更新,但这题可以避免,下面会给出注释。#include #include #include #include #include #include原创 2016-03-13 13:31:10 · 1078 阅读 · 0 评论 -
HDU 4288线段树开动脑筋
点击打开链接题意:有几种操作,add加入一个数,del删除一个数,问所有下标%5==3的数的和思路:看题就知道是线段树,又有加入又有删除又有求和的,线段树无疑,可是问的是下标%5==3的数的和,我们可以令开一个数组cnt,记录区间数字的个数,这样我们开一个num数组,二维的,后面的[5]分别记录区间的下标%5==0,1,2,3,4的数的和,在更新的时候,如果要求num[][3]的值,则左儿原创 2016-04-06 14:00:49 · 752 阅读 · 0 评论 -
coderforces round 19D线段树+离散化处理
点击打开链接题意:共有三种操作,add:向平面中加入一个点x,y,remove:将平面中的一个点删除,find x,y查询平面内严格大于x,y的点,要求这个点横坐标越小越好,然后再保证纵坐标越小越好,不存在这样的点输出-1。思路:因为x,y的范围很大,所以先将x坐标的值离散化,然后以x的位置和对应y的值保存到set中,线段树节点保存区间最大值,查询时也查询大于x的位置,然后二分求得y的位置原创 2016-03-12 11:51:56 · 877 阅读 · 0 评论 -
HDU1394线段树求逆序数
点击打开链接题意:输入n个数的序列,依次将第一个数放到最后面,求这期间的最小逆序数思路:挺简单的一道线段树,下面注释中有解释。#include #include #include #include #include using namespace std;typedef long long ll;const int maxn=5010;const int inf=0x3原创 2016-03-11 18:31:07 · 2258 阅读 · 0 评论 -
HDU4288线段树+离散化
点击打开链接题意:一共有三种操作,add添加一个元素,del删除一个元素,sum查询下标%5==3的所有元素的和。思路:有整个区间的一个查询,自然想到线段树,只不过这次的要%5==3的一个条件,在更新父亲信息的时候做了改变。离散化无非就是将所有数去重,然后一个一个处理。至于更新时的变化下面给了解释。#include #include #include #include #i原创 2016-03-11 16:29:36 · 870 阅读 · 0 评论 -
POJ2828线段树
点击打开链接题意:一个人接一个人的插队,后面的人更厉害,可以要到自己想要的位置。思路:既然后面的优先,那就从后面开始进入队列中,知道从后面开始就简单多了。#include #include #include #include #include using namespace std;typedef long long ll;const int maxn=200010;c原创 2016-03-09 20:41:47 · 800 阅读 · 0 评论 -
HDU2795线段树之单点更新
点击打开链接题意:在一块h*w的矩形板上,要求贴1*Wi的广告,尽量往左往上的贴广告,如果贴不上的话,输出-1;否则输出这个小广告贴在了第几行上。分析:可以用线段树保存每一行的长度,贴上广告之后便更新自己的值,线段树可以做到快速的查询和更新,下面有注释。#include #include #include #include #include using namespace std;原创 2016-03-09 19:30:05 · 545 阅读 · 0 评论 -
HDU 1698 线段树成段更新
点击打开链接题意:给你T组数据,每组N个数,初始为1,M个操作,每个操作将区间a到b的值更新为才,问n个数的和。思路:简单的线段树成段更新,需要用到懒惰标记,说白了懒惰标记就是用到的时候再去更新它,不然就放在那里#include #include #include #include #include using namespace std;const int inf=0x3原创 2016-03-16 20:53:50 · 1732 阅读 · 0 评论 -
POJ 2481 线段树
点击打开链接题意:有N头牛,每只牛有一个测试值[S,E],如果对于牛i和牛j来说,它们的测验值满足下面的条件则证明牛i比牛j强壮:Si Ej - Sj。现在已知每一头牛的测验值,要求输出每头牛有几头牛比其强壮。思路:将S从小到大排序,E从大到小排序,这样就保证第一个条件满足,线段树保存时与求逆序数的方法相同,求出比当前牛强壮的个数。#include #include #inclu原创 2016-03-13 17:47:21 · 765 阅读 · 0 评论 -
hdu 1542 线段树之扫描线之面积并
点击打开链接题意:给你n个矩形,求它们的面积,重复的不重复计算思路:用线段树的扫描线完成,将X坐标离散化后,从下到上扫描矩形,进行各种处理,看代码注释把#include #include #include #include #include using namespace std;typedef long long ll;const int maxn=1e3+10;#def原创 2016-03-24 20:44:14 · 1817 阅读 · 0 评论 -
HDU 1828 线段树之扫描线之周长并
点击打开链接题意:给n个矩形,求它们重叠后的周长思路:用线段树的扫描线从下到上扫一遍,与面积并思想有些相似面积并,下面重边的处理相似,但是周长的并需要求的是竖边的个数然后乘以高度,而面积并求的是底边的长乘以高度,这里我们用了区间合并时的lnum和rnum,具体下面有注释#include #include #include #include #include using names原创 2016-03-25 11:41:49 · 1140 阅读 · 0 评论 -
NEFU 1160 线段树
点击打开链接题意:弱校的OJ的弱题,给定一棵树,和关系,然后在节点上更新时,它的所有儿子也要更新,有个判断条件,查询是所有节点的值的和思路:与HDU 5692一样的思路,不多说了#pragma comment(linker, "/STACK:102400000, 102400000")#include #include #include #include #include #i原创 2016-05-22 10:46:59 · 3757 阅读 · 0 评论 -
HDU 5692 线段树
点击打开链接题意:中文题目思路:这还是第一次写这样的线段树,个人感觉是一种套路之前没做过,但是思想什么巧妙,将一颗树转化成线段树真厉害,先是将每个节点的下面的所有数进行dfs编序号,并将他们的左右编号记下来,也就是我的代码中的L和R,而val记录的是根节点0到当前位置的费用,建树之后就很好操作了,更新时便找到当前节点的儿子和自己代表的区间,然后区间更新,注意题目说更新一个节点的值变为y,我原创 2016-05-21 19:58:18 · 6107 阅读 · 0 评论 -
UVALive 4730 线段树+并查集
点击打开链接题意:在坐标上给n个点,r的操作是将两个点连起来,l的操作是问你y=u的这条线连接的集合块数和这些集合内的点的个数思路:很麻烦的一道题,在网上看了题意和做法后,开始了一下午的调bug过程,做法很好懂,我开了两个线段树,一个维护点代表的直线的集合个数,另一个则是路过集合内的点的个数,然后集合的判断直接用并查集就行了,这是两个核心,然后就是自己瞎写的了,代码丑的可以而且好像除了原创 2016-05-29 19:52:07 · 3303 阅读 · 0 评论