
数据结构-线段树
Endless_Way
这个作者很懒,什么都没留下…
展开
-
BZOJ 1012 [JSOI2008]最大数maxnumber
不明觉厉地打了线段树就A了。#include<cstdio>#include<algorithm>#define MAX 200010using namespace std;struct segment{int v, l, r;}node[MAX*10];int cnt=0;void build(int x, int l, int r){ node[x]=(segment){0原创 2016-08-01 13:12:31 · 233 阅读 · 0 评论 -
BZOJ 3711 [PA2014]Druzyny
DP+分治+线段树似乎有另一种O(nlogn)O(nlogn)的做法,就不详细说了。说一种O(nlog2n)O(nlog^2n)的做法。考虑分治,对于区间[l,r][l,r],用[l,mid][l,mid]来贡献[mid+1,r][mid+1,r]。 对于一组贡献,设j∈[l,mid],i∈[mid+1,r]j \in [l,mid], i \in [mid+1,r]。 jj 能贡献给ii原创 2017-03-02 07:37:49 · 654 阅读 · 0 评论 -
CF 240F TorCoder
线段树题目名称有意思- -用线段树维护区间各个字母出现次数即可。 然后做回文串就贪心从小往大放。#include<cstdio>#include<cstring>#define N 100005#define A 27using namespace std;namespace runzhe2000{ char str[N]; int v[A]; struct se原创 2017-01-27 11:27:30 · 357 阅读 · 0 评论 -
BZOJ 4515 [Sdoi2016]游戏
李超线段树就是区间cmin一次函数,只不过被搬到树上来了。李超线段树标记永久化搞一搞就行了。O(nlog^3)具体地。每一个节点表示一个区间,存储一个一次函数,表示在该区间的优势一次函数,即能取到最小值的一次函数。更新的时候一整条往下扫一下即可。大年初一凌晨敲道农题压压惊UPD(2017.4.8):震惊!突然发现自己下面的代码是错的。注意下面代码里标记的地方。正确的代码附在后面了。话说这题数据好像不原创 2017-01-29 00:18:47 · 334 阅读 · 0 评论 -
UOJ 228 基础数据结构练习题
线段树 多写点骗点访问量 加法好说,开平方就很气了,因为开平方的信息不能合并。这样就导致常规的线段树,分块之类的维护数列和的方法不能用。我们只能另辟蹊径,找寻性质。我们发现开平方操作会让数字减少得很快,大概六七次就能把一个数变成1。这给我一种在不特意构造数据的情况下,最终数字很容易变得大部分都一样的感觉。如果没有加法,那只要判断一下区间里有没有非1的,有就暴力做,这样复杂度没问题。考虑有加法,加法会原创 2017-03-25 17:54:04 · 1522 阅读 · 0 评论 -
51Nod 1559 车和矩形
线段树+扫描线考虑符合题意的充要条件,是每一行每一列都有一个车?并不,显然可以构造出一行没有的合法情况,但此时必须是每一列都有车,因此充要条件是每一行都有车或每一列都有车。两种情况分开来做,考虑怎么判断每一行都有车。扫描线,按y轴排序,每一个矩形就相当于区间询问,只需判断区间里此时每一行的最近的车中最远的在哪,如果落在矩形外就不行了,于是只需求区间最小值。#include<cstdio>#incl原创 2017-04-02 00:28:57 · 568 阅读 · 0 评论 -
BZOJ 4553 [Tjoi2016&Heoi2016]序列
分治+线段树记l[i]表示i可能变成的最小值(包括a[i]),同理r[i]最大值。显然i能从j转移当且仅当i#include<cstdio>#include<algorithm>#define cmin(u,v) ((u)>(v)?(u)=(v):0)#define cmax(u,v) ((u)<(v)?(u)=(v):0)#define N 100005using namespace s原创 2017-04-02 00:31:09 · 400 阅读 · 0 评论 -
BZOJ 4825 [Hnoi2017]单旋
splay 或 线段树观察这种spaly的性质。插入一个点,这个点的深度就是它的前驱后继中深度较大的那个+1。单旋最小值,则最小值的右子树里的点深度不变,自己深度变为1,其他点深度+1,单旋最大值同理。删除则在这个基础上让全部深度-1。这个是在平衡树上的子树维护,也就是一个区间维护,离线上线段树即可。然而我还是带着敬意地写了一个splay……#include<set>#include<cstdio原创 2017-05-01 13:43:29 · 444 阅读 · 0 评论 -
UOJ 112 & BZOJ 4071 [Apio2015]巴邻旁之桥
线段树同侧的显然不用管他。k=1。枚举啊三分啊什么的应该都能过。进一步地,桥的位置一定是中位数。k=2。发现没有什么二分三分之类的性质。假设两座桥已经定下来,那么一个居民会选择离(A+B)/2近的桥来走。也就是按(A+B)/2排序后,居民会被分成左右两波走不同的桥。那就枚举分界点,对于走同一座桥的,类似k=1的找出中位数,用线段数维护中位数。#include<cstdio>#include<alg原创 2017-05-04 13:14:48 · 459 阅读 · 0 评论 -
BZOJ 4540 [Hnoi2016]序列
线段树+矩阵我来发一篇博客证明我还活着题目要求的区间所有子区间的最小值之和不太容易合并,因此直接上数据结构不好做。考虑离线做法。把所有询问右端点排序。从左到右扫描整个序列,扫描到ii时维护所有1≤j≤i1\le j\le i的区间[j,i][j,i]的答案。那每做完一个ii只要抓出当前询问的区间查询即可。如何随着ii右移,动态地维护前缀所有区间的答案?新加一个ii进来的时候,只会增加右端点在ii的子原创 2017-06-20 13:55:39 · 369 阅读 · 0 评论 -
LOJ 6041 「雅礼集训 2017 Day7」事情的相似度
LCT+SAM+线段树问一个区间里的前缀之间的最长公共后缀,考虑SAM一发,建出反串后缀树,然后求最长公共后缀就变成求最深的LCA。直接维护区间的答案不好做,因此考虑一些离线的算法。莫队不知道能不能做,这里考虑把询问按照右端点排序,然后从左到右扫一遍。扫到i,则维护所有左端点在1~i-1,右端点在i的区间的答案。i新贡献的答案就是i和1~i-1的最公共后缀,也就是后缀树上一个点和其它一些点的最深LC原创 2017-06-24 17:34:53 · 1584 阅读 · 0 评论 -
LOJ 6032 「雅礼集训 2017 Day2」水箱
线段树合并+树状数组把0设成-1,问题就变成求最大前缀和。考虑一个DP,记f[i]表示i隔板隔住了水,i之前最多满足多少条件。转移的时候枚举j表示[j,i]能是一个以j,i为左右端点的装水区间。这样的问题是每次从新的i扫到一个j都要合并一遍区间里的所有标记,也就是一个区间会被合并多次。然而能够证明,不同的装水区间不超过O(n)个,且它们之间不会有交(端点可能相同)。因此先找出这些区间,线段树维护一个原创 2017-06-28 07:54:54 · 956 阅读 · 0 评论 -
BZOJ 2865 字符串识别
后缀自动机+线段树考虑最终包含点i的仅出现一次的子串长什么样。记这个子串是[l,r]。l < i < r : 即i不碰到左右端点,对于这种情况,可以暴力在SAM上找出所有出现一次的串,用线段树更新答案。l = i ≤ r : 设以r为右端点的出现一次的最短的串为[l’,r],显然要有l≤l’。于是依然可以暴力找出所有出现一次的串,用r来更新[1,l-1]的答案。l ≤ i = r : 设以r为右端点原创 2017-01-14 20:33:00 · 495 阅读 · 0 评论 -
UOJ 88 [集训队互测2015]Robot
线段树分治套凸包每个机器人在多次修改之间的贡献是不同的,因为这个一次函数被修改。显然要线段树分治。我们需要在线段树上维护凸壳,刚开始我以为要用动态凸包的那套理论。后来才知道直接在外面给所有一次函数排序,做凸壳就能是线性的了。。。我真智障#include<cstdio>#include<algorithm>#define N 500005#define cmax(u,v) (u)<(v)?(u)原创 2016-12-31 22:47:46 · 748 阅读 · 0 评论 -
BZOJ 4538 [Hnoi2016]网络
线段树上二分+链交+LCA这题做法大概有2种,我用的是第二种1.实际上一条链的贡献是这条链在树上的补集,于是树剖线段树维护树,每一个节点开一个堆维护最大贡献。 O(nlog3n)O(nlog^3n)2.假设对于一个询问x,二分出一个答案C,若所有≥C的链都经过了x,则显然最终答案<C,否则最终答案≥C。于是离线将所有链按权排序后,建立权值线段树,节点存储子节点的链交,直接在线段树上二分找答案即可,O原创 2016-12-06 10:37:39 · 685 阅读 · 0 评论 -
BZOJ 1036 [ZJOI2008]树的统计Count
首先树链剖分。要支持求极值,求和,修改,把所有树链加入线段树进行维护即可。#include<cstdio>#include<algorithm>#define MAXN 30010using namespace std;struct edge{int next,to;}e[MAXN*2];struct segment{int sum, maxx, l, r;}node[MAXN*10];原创 2016-08-01 22:08:08 · 323 阅读 · 0 评论 -
BZOJ 4034 [HAOI2015]T2
树剖+线段树要能够一次性给子树赋值,可以用DFS序+线段树 要查询点到根的路径和,树剖+线段树 于是用树剖的DFS序建树#include<cstdio>#define N 100005#define ll long longusing namespace std;struct edge{int next,to;}e[N<<1];struct segment_tree{int l, r;原创 2016-09-25 13:47:58 · 301 阅读 · 0 评论 -
BZOJ 3688 折线统计
线段树维护DP令f[i][j][0/1]表示前i个点,选择j段,最后一段是下降/上升的方案数。f[i][j][0]=∑(f[k][j][0]+f[k][j-1][1]) (k < i且a[k].y>a[i].y)f[i][j][1]=∑(f[k][j][1]+f[k][j-1][0]) (k < i且a[k].y#include<cstdio>#include<algorithm>#define原创 2016-09-27 14:35:02 · 432 阅读 · 0 评论 -
SPOJ GSS 1~8
GSS是一系列查询区间最大子段和及其变种的题目。GSS 1 ~ 8 的题号分别是:1043 & 1557 & 1716 & 2713 & 2916 & 4487 & 6779 & 19543 目前完成进度:1 (好惨啊,慢慢做吧……)SPOJ 1043 GSS 1应该是不难的。我们假设一个区间的最大子段已经找到,往区间里随便放一条分界线。有两种情况:一是最大子段在分界线的某一边,二是最大子段经过分界原创 2016-10-22 00:01:04 · 1372 阅读 · 1 评论 -
BZOJ 2725 [Violet 6]故乡的梦
堆优dijkstra+线段树膜:http://blog.youkuaiyun.com/popoqqq/article/details/47841783为了表达清楚,记不删边时最短路为E1,删去某一条E1上的边之后的最短路为E2显然E2一定是形如:S->沿着E1走到某一个在E1上点的S’->沿着不属于E1的一些边走到某一在E1上点的T’->沿着E1走到T而且可以证明,上面提到的E2中不属于E1的那些边(组成一条路原创 2016-10-15 14:01:04 · 595 阅读 · 0 评论 -
BZOJ 4552 [Tjoi2016&Heoi2016]排序
二分+线段树本蒟蒻完全想不到二分啊。。。二分答案x。设小于等于x的值为0,大于x的值为1。排序的时候我们只关心x是否会出现在P位置上,而x的位置只和区间内小于它的数和大于它的数有关,所以不关心其他的值具体是多少,直接线段树维护赋值查询即可。#include<cstdio>#define N 100005using namespace std;struct opt{ int l, r,原创 2016-10-15 15:16:58 · 335 阅读 · 0 评论 -
BZOJ 3526 [Poi2014]Card
线段树对于两个区间,如果我们知道前一个区间的开头卡片的不同选择(正面或反面)的结果,和后一个区间开头不同选择的结果,那么我们肯定能将他们合并,从而得到整个区间开头不同选择的结果。考虑线段树。f[i][0 / 1]表示i区间以正面/反面开头的单调不降序列是否存在,不存在记-1,存在就记最后一个卡片最小能选正面还是反面#include<cstdio>#include<algorithm>#defin原创 2016-10-02 13:47:41 · 382 阅读 · 0 评论 -
BZOJ 3626 [LNOI2014]LCA
树链剖分+线段树+离线挂题解:http://blog.youkuaiyun.com/popoqqq/article/details/38823457主要思想:对于询问[l,r]和z,可以把[l,r]的每一个点到根的路径上的边的权值分别+1,计算z到根的路径权值和就是所求询问。于是离线排序做即可。好巧妙- -#include<cstdio>#include<algorithm>#define N 50005原创 2016-10-02 18:33:20 · 373 阅读 · 0 评论 -
BZOJ 3295 [Cqoi2011]动态逆序对
树状数组套线段树线树状数组维护一整个序列,线段树维护当前区间的元素取值。单次操作O((logn)^2)题不错,就是有点卡内存- -#include<cstdio>#include<cstring>#define N 100005#define lowbit(_i) (_i&-_i)#define ll long longusing namespace std;int n, a[N], p原创 2016-10-18 09:29:49 · 283 阅读 · 0 评论 -
BZOJ 3333 排队计划
每排序一次,减少的只能是在p的右边由所有小于等于h[p]的数构成的逆序对。用线段树维护区间最小值,没个数只需访问一次,总时间复杂度O(nlogn)#include<cstdio>#include<algorithm>#define N 500005#define ll long long#define lowbit(_i) (_i&-_i)using namespace std;stru原创 2016-10-29 13:49:05 · 391 阅读 · 0 评论 -
BZOJ 3600 没有人的算术
线段树+替罪羊树黄学长博客里有VFK大爷的题解题意即给出一类嵌套结构的类似pair的“数”,定义它们之间的大小比较为递归比较first和second。(设first和second分别为数的括号里的左右两边)查区间max,可以考虑线段树,那么重点就是如何快速判断两个数的大小。暴力比较可以有30分。注意到后面有两个点的出现数字个数不超过1000,暗示我们可以直接处理出所有数对的大小关系,可以有50分。然原创 2016-12-10 15:51:55 · 609 阅读 · 0 评论 -
BZOJ 4345 [POI2016]Korale
模拟搜索+线段树我觉得这题挺妙的啊。注意到当n=1000000很大的时候会有2^1000000种取法,但题目只要求选到k=1000000个,也就是我们不能爆搜,但要保证每一次都能取到一个前k大的。也就是要进行一个优秀的搜索。考虑朴素的垃圾搜索,是每次枚举i选或者不选,然后搜索i+1。注意到搜索的下一层的和总大于上一层。因此把其中有用的节点拿出来,是一个树形结构,若当前在第i层,有两种决...原创 2018-07-18 23:27:17 · 311 阅读 · 0 评论