各种线段树
文章平均质量分 84
李超线段树/权值线段树/动态开点线段树
黑夜和白天
过去无可挽回,未来可以改变
展开
-
树套树 ----- P1975 [国家集训队]排队(树状数组套权值线段树求动态逆序对)
解题思路:首先我们知道交换两个数a[l]和a[r]a[l]和a[r]a[l]和a[r]影响到的区间是[l+1,r−1][l+1,r-1][l+1,r−1]对于a[l]a[l]a[l],我们要减去[l+1,r−1][l+1,r-1][l+1,r−1]里面比a[l]a[l]a[l]大的,加上比a[l]a[l]a[l]小的。对于a[r]a[r]a[r]同理反过来就好了。如果a[l]>a[r]:ans++a[l]>a[r]:ans++a[l]>a[r]:ans++如果a[r]>a原创 2021-10-09 10:51:29 · 130 阅读 · 0 评论 -
树套树 ---- 树状数组套权值线段树模板题 P2617 Dynamic Rankings 动态第K大
题目链接题目大意:给你一个数组aaa,aaa有两个操作询问aaa中[l,r][l,r][l,r]区间里面第kkk小的数是哪个?修改axa_xax为yyy解题思路:首先我们知道权值线段树是可以求第kkk小的数的,如果只有第一个问题那么就是一个主席树问题,但是主席树对于第二个问题,要修改nnn棵树时间复杂度是O(nlogn)O(nlogn)O(nlogn)的很大不行我们知道主席树是怎么建立的?是root[i]继承了root[i−1]的到的连续区间的权值线段树root[i]继承了root原创 2021-08-12 08:47:45 · 99 阅读 · 0 评论 -
线段树分治 ---- F. Extending Set of Points(线段树分治 + 可撤销并查集)
题目链接题目大意:你有个点集合SSS,每次往集合里面加点或者删点(如果要加的点出现过),如果(x1,y1),(x2,y1),(x1,y2),(x2,y2)(x1,y1),(x2,y1),(x1,y2),(x2,y2)(x1,y1),(x2,y1),(x1,y2),(x2,y2)只要出现其中3个第4个就会出现?问你最终这个点集会变成多少个点在里面解题思路:很明显的一点4个点连线会构成一个环,我们对这个点我们可以直接用并查集去维护行和列拆开例如(x1,y1)(x1,y1)(x1,y1)我们直接把原创 2021-10-13 14:55:35 · 90 阅读 · 0 评论 -
线段树分治 ---- CF1217F - Forced Online Queries Problem(假离线 可撤销并查集 + 线段树分治)详解
题目链接题目大意解题思路:我一开始想到可以用可撤销并查集去维护这种删边加边的操作,但是有个缺点是每次撤销都有把后面的边全部撤销复度是O(n2)O(n^2)O(n2)首先我们考虑这种动态加边删边的问题,如果是离线的话,那就是线段树分治+可撤销的并查集的模板题但是这是强制在线,但是这是虚伪的强制在线就是,每次个操作最多有两种的结果。lst={0,1}lst=\{0,1\}lst={0,1}, 最多也就2×m2\times m2×m个操作就是我们有条有若干段存在的时间,我们插进线段树里面,用原创 2021-09-29 20:55:27 · 183 阅读 · 0 评论 -
线段树 ---- H. AND = OR (或和与的性质之1的个数 + 线段树)
题目链接题目大意:给你一个序列{a}\{a\}{a},每次询问一个区间[l,r][l,r][l,r]问你这个区间里面的数是否可以分成两部分使得一部分的AND=AND=AND=另一部分的OROROR解题思路:这个题思路很妙:首先我们知道对于&\&&操作数越多只会越&\&&越小,而∣|∣就是相反的那么我们可以假设这个区间里面的数可以分成两部分,那么假设最后的答案是ansansans假设ansansans中有xxx个1,那么对于区间里面数包含的原创 2021-10-06 20:51:17 · 334 阅读 · 0 评论 -
线段树 ---- CF452F. Permutation(线段树维护序列Hash)
题目链接题目大意:就是给你一个全排列,问你是否存在一个c=a+b2c=\frac{a+b}{2}c=2a+b满足ccc的位置在a,ba,ba,b之间解题思路:首先我们先按顺序遍历,我们假设遍历到的数是中间那个数就是ccc,那么它要存在的答案的话就是存在一个kkk,使得c−k在之前出现过,c+k还没出现,或者反过来c-k在之前出现过,c+k还没出现,或者反过来c−k在之前出现过,c+k还没出现,或者反过来我们设bib_ibi表示iii这个数是否出现过?那么如果ccc这个数没有答案呢?就原创 2021-09-24 20:16:03 · 108 阅读 · 0 评论 -
线段树 ---- D. Power Tree(离线dfs序+线段树维护树上多条路径和的技巧)
题目链接题目大意:一开始给你只有一个点111的树,有qqq次询问。每次询问有两种操作1 p v1\;p\;v1pv 就是把最小的没加入的点,加入这个树,它的父亲是ppp,权值是vvv2 u2\;u2u 就是询问你u的Strength(Su)Strength(S_{u})Strength(Su)是多少?SuS_uSu的直接定义是一个集合这个集合包括这个点里面所有的直接儿子的Strength(Sson)Strength(S_{son})Strength(Sson),和当前点的权值组成原创 2021-09-23 20:29:54 · 199 阅读 · 0 评论 -
线段树 ---- CF1004F Sonya and Bitwise OR(线段树上分治合并区间信息 + or 前缀和的log性质)
题目链接题目大意:解题思路:考虑只有一次询问时怎么做。分治。每次考虑LLL位于左半边,RRR位于右半边的情况(也就是“跨过中点”的答案)。再分别递归左、右两边。计算跨过中点的答案时,可以先求出【左半边的or\operatorname{or}or值后缀和】和【右半边的or\operatorname{or}or值前缀和】。然后用two pointers求出满足条件的(L,R)(L,R)(L,R)数量,例如,可以枚举RRR,则左半边的LLL可选范围单调增加,也就是从最左边不断向右移。这样,不原创 2021-09-15 20:45:07 · 127 阅读 · 0 评论 -
线段树 ---- 线段树上区间二分 或者单点二分 codeforces C. Greedy Shopping
题目大意题目大意:给你一个非增的区间现在你有两次操作1 x y : 把[a1,...ax][a_1,...a_x][a1,...ax]里面的数对yyy取maxmaxmax2 x y : 你有yyy元,从xxx到nnn,每次遇到一个aia_iai,如果你比它大你就减掉aia_iai,问你可以减多少次?MY solution一开始看一眼对于第一个操作是没问题的,但是对于第二个操作我们怎么搞?假设你能减xxx次,那么每次减的数是集合{b}\{b\}{b}满足b1>b2>原创 2021-09-10 22:17:59 · 187 阅读 · 0 评论 -
线段树 + 树形换根 + dfs序 ---- 离线启发式求解 (有点像树上启发式合并答案) F. Nearest Leaf
题目链接题目大意:就是给你一个有根树,每个点都有一个编号,编号是它们的dfsdfsdfs序,现在qqq次询问,每次询问给你一个点vvv和一个区间[l,r][l,r][l,r],问你,这个区间里面的叶子节点,距离vvv最近的距离是多少?每条边是有边权的n,q∈[1,5e5]n,q\in[1,5e5]n,q∈[1,5e5]解题思路:首先我开始想在线处理但是太麻烦了。对于这么多询问的还不强制在线的多半是离线处理!!根据dfsdfsdfs序我们很容易联想到线段树,唉这里还有个区间查询。那么我原创 2021-09-08 19:47:43 · 88 阅读 · 0 评论 -
单调栈 or 线段树扫描线 ---- E. Delete a Segment [单调栈+二分] [扫描线处理空白位置的技巧乘2]
题目链接题目大意:给出nnn个线段代表集合,现在问若可以将其中任意一个线段删除,则能够形成最多多少个独立的集合(取并集后)解题思路1:首先我们先对线段按照起点排序那么我们枚举删除的线段iii,那么整个区域就切成了[1,i−1][1,i-1][1,i−1]和[i+1,n][i+1,n][i+1,n]的两段现在我们就是要把[1,i−1][1,i-1][1,i−1]和[i+1,n][i+1,n][i+1,n]里面的线段合并就可以了我们要把[1,i−1][1,i-1][1,i−1]里面的线段算原创 2021-09-02 12:27:08 · 63 阅读 · 0 评论 -
线段树 ---- 线段树维护线段相加+滑动变长窗口 2021牛客多校第7场 F xay loves trees
题目大意:给你两个大小相同的树但是形状不一定一样叫你选出最大的子集,满足下面两个条件在第一颗树上是一条链在第二颗树上任意两个点都不是祖先关系解题思路:首先我们现在第二颗树上面把每个点的dfs序处理处理,那么就变成在第一颗树上面找到最长的一条链,链上点的dfs序区间都不相交,祖先关系的点会存在下图关系那么最开始我们想的是二分最大长度然后每次都去维护固定长度的链,每次区间修改(区间覆盖),O(1)O(1)O(1)查询,但是是O(nlog2n)O(nlog^2n)O(nlog2n)过不来原创 2021-08-07 19:50:29 · 110 阅读 · 0 评论 -
线段树 ---- 2021牛客多校第一场 J Journey among Railway Stations [线段树维护区间可行性判断]
题目链接题目大意:一段路上有 NNN 个点,每个点有一个合法时间段[ui,vi][ui,vi][ui,vi],相邻两个点有一个长度wiwiwi。有qqq次询问,每次询问,在 [ui,vi][ui,vi][ui,vi]的时间段从iii出发后,能否依次经过i+1到ji+1到ji+1到j的所有点,使得到达时间满足每个点的合法区间(如果提前到可以等待,迟到了失败了)。同时还可能修改一段路的长度,或者修改一个点的合法时间段。N,q∈[1,1e6]N,q\in[1,1e6]N,q∈[1,1e6]解题思路:原创 2021-08-30 19:38:11 · 70 阅读 · 0 评论 -
线段树 ---- 牛客多校4 ETree Xor 区间异或分段
题目链接题目大意:就是给你nnn个节点的树,树上每个节点都有一个权值wi∈[li,ri]w_i\in[l_i,r_i]wi∈[li,ri],以及相邻(u,v)(u,v)(u,v)的异或值wuXORwvw_uXORw_vwuXORwv问你w1...nw_{1...n}w1...n有多少种取值?解题思路:我们知道如果一个节点的权值定下来的话,那么整颗树的所有点的权值都定下来了!现在我们假设w1′=0w'_1=0w1′=0那么我们就可以解出w2....n′w'_{2....n原创 2021-07-27 10:04:46 · 211 阅读 · 2 评论 -
线段树 ---- 牛客多校2021多校第6场 H Hopping Rabbit 扫描线
思维误区:扫描线扫描线模板里面有两个变量一个是cover和lengthcover和lengthcover和lengthcovercovercover是标记下面是否覆盖满了,但是covercovercover等于000也有可能覆盖满的所以只能通过lengthlengthlength去判断代码:#include <iostream>#include <cstdio>#include <stack>#include <sstream>#in..原创 2021-08-03 11:45:55 · 104 阅读 · 0 评论 -
线段树 ---- Codeforces 737 Div2 D. Ezzat and Grid 维护dp
题目链接题目大意:就是给你很多行的010101串,长度是1e91e91e9,每一行都有若干段的连续的111,对于给定的串集合是美丽的美丽的美丽的的条件是任意相邻两行的串至少有一个列是同时有111的,问你至少删除多少行使得这些010101是美丽的?n,m∈[3e5]n是行数,m是线段数n,m\in[3e5]n是行数,m是线段数n,m∈[3e5]n是行数,m是线段数输入是i,l,ri,l,ri,l,r意思是第iii行的[l,r][l,r][l,r]的范围内是111解题思路:这个题目有个比较麻烦原创 2021-08-10 16:03:29 · 225 阅读 · 1 评论 -
线段树分裂与合并的模板以及空间大小的计算
学习知识来自AGOH的B站视频模板题#include <bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 2e5 + 10;struct node {//权值线段树 动态开点 int l, r; ll val;}sgt[(maxn+10) * 40];int cnt, root[maxn+10];int n, m;void pushup(int rt) { sgt[rt].v原创 2021-08-05 09:19:05 · 103 阅读 · 0 评论 -
线段树分裂与合并 ---- 树上差分 P4556 [Vani有约会]雨天的尾巴 /【模板】线段树合并
题目链接解题思路:首先题目是对u,vu,vu,v这两条路径上面添加一个zzz,然后运用树上点的差分思想,对于分发路径u,vu,vu,v,我们在uuu上+1+1+1,在vvv上+1+1+1,在lca(u,v)lca(u,v)lca(u,v)处−1-1−1,在fa(lca)fa(lca)fa(lca)处−1-1−1,最后统计时自底向上做树上前缀和但是每次加的种类不一样,使用线段树合并,每个节点维护一棵权值线段树,下标为救济粮种类,区间维护数量最多的救济粮编号(下标)。所以每个节点答案即为。代码有详细原创 2021-08-05 10:55:21 · 92 阅读 · 0 评论 -
线段树分裂与合并 ----- P2824 [HEOI2016/TJOI2016]排序 [线段树分裂合并 OR 01序列排序+二分线段树]
题目链接解法一:二分+线段树首先我们知道对一个01序列进行排序是很快的!我们只要知道里面有多少个1和多少个0,那么我们就可以用线段树区间修改每次排序才O(logn)O(logn)O(logn)完美!但是怎么融入到这道题里面呢?我们先二分出一个值midmidmid,把比mid≤nummid\leq nummid≤num的值全部设置成1,其他全是0,然后排序一遍,如果排完序后那么qqq位置是1的话,那么它排序之后就肯定大于或者等于当前的midmidmid,那么我们就可以确定二分的方向了!!时间复杂度原创 2021-08-08 09:38:03 · 112 阅读 · 0 评论 -
线段树合并与分裂维护树上最长上升子序列 + 点分治删点 ---- 2021 牛客多校第一场 C - Cut the tree(详解)
题目大意:给你一个树,树上每个点都有一个权值valnodeval_{node}valnode,路径(u,v)(u,v)(u,v) 上所有点按顺序有序序列,令f(u,v)f(u,v)f(u,v)是这个序列的最长上升子序列的长度,设GGG是max(f(u,v))∣(u,v)是可达的max(f(u,v))|(u,v)是可达的max(f(u,v))∣(u,v)是可达的现在叫你删除一个点vvv使得GGG最小解题思路:思路1:求解树最长上升子序列怎么求?首先我们先假设是对一个有根的树求对于一个dp[i原创 2021-08-23 17:00:07 · 176 阅读 · 0 评论 -
可持久化普通线段树 ---- P2839 [国家集训队]middle 可持久化普通线段树 + 二分 求中位数最大值
题目链接题目大意:解题思路:这个题思路很妙!!首先我们假设只有一次询问怎么做?那么我们可以二分出这个最大值midmidmid,然后把大于等于midmidmid设置成111,把小于midmidmid的设置成−1-1−1,那么就是看看能否构造出一个区间的和大于等于000?因为区间两端在[a,b][a,b][a,b]和[c,d][c,d][c,d]之间移动,那么[b+1,c−1][b+1,c-1][b+1,c−1]之间是一定会取到的,为了中位数最大那么区间和肯定要最大!!那么就找[a,b][原创 2021-08-13 11:02:42 · 68 阅读 · 0 评论 -
szu 寒训个人复习第一天 线段树入门单点修改,区间修改,以及线段树的扩展运用[线段树+dp][区间最大公约数]
寒讯内容有点过多(其实是我太菜了) 水一波怕忘了(人老了) **什么是线段树**线段树是本蒟蒻感觉用处特别大的算法那么线段树上面的节点表示什么意思呢?线段树,上面的节点表示一个区间,父亲节点表示的区间是左右儿子相加.同一...原创 2020-02-28 22:06:17 · 1537 阅读 · 0 评论 -
李超线段树(Li-Chao Segment Tree)
李超线段树李超线段树是一种用于维护平面直角坐标系内线段关系的数据结构。它常被用来处理这样一种形式的问题:给定一个平面直角坐标系,支持动态插入一条线段,询问从某一个位置 (X,+∞)(X,+\infty)(X,+∞) 向下看能看到的最高的一条线段(也就是给一条竖线,问这条竖线与所有线段的最高的交点如上图,有三条线段,两条红色竖线代表两个询问,则点 AAA 与点 BBB 就是询问到的答案。李超线段树的核心是维护每个区间的“最优势线段”,即在每个区间的中点处最高的线段。询问时我们可以对所有包含横坐标为转载 2020-11-10 19:05:54 · 839 阅读 · 0 评论 -
动态开点线段树的模板
#include<bits/stdc++.h>#define lowbit(x) ((x)&(-x))#define Finline __inline__ __attribute__ ((always_inline))#define DEBUG fprintf(stderr,"Running on Line %d in Function %s\n",__LINE__,__FUNCTION__)#define SZ(x) ((int)x.size())#define mkpr原创 2020-05-19 16:06:53 · 547 阅读 · 0 评论 -
权值线段树的模板
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<cmath>#include<queue>using namespace std;const int maxn...原创 2020-05-03 11:00:56 · 131 阅读 · 0 评论