线段树

[学习笔记]线段树合并

橙三吉。 提交于 2020-03-09 20:06:38
1、[POI2011]ROT-Tree Rotations 分析:线段树合并人生第一题。 网上的题解我都没看懂……我自己讲一下好了 线段树合并就是把两棵权值线段树合并到一棵 那怎么合并呢? 假设有这么两棵树: 一个结点代表一段值域区间有几个数,那么可以看出合并后应该是这样的 然后具体步骤就是找到一个结点,如果一个结点一棵树上有一棵树上没有,那么直 接返回那个结点的编号,否则两个值域的和相加,递归至左儿子和右儿子 每次合并的复杂度为两棵线段树的点数相加 这道题可以算出左儿子的逆序对个数,右儿子的逆序对个数,然后求出 \((x,y)\) 的对数, $x\in $ 左儿子, $y\in $ 右儿子 每次记录一下 \(sum\) ,在每次合并的时候 \(sum[lson[x]]\times sum[rson[y]]\) 和 \(sum[rson[x]]\times sum[lson[y]]\) 中取个最小值算进答案的贡献就可以了(不懂可以自己画图或看代码理解一下) \(Code\ Below:\) #include <bits/stdc++.h> #define ll long long using namespace std; const int maxn=200000+10; int n,L[maxn*24],R[maxn*24],sum[maxn*24],cnt; ll ans

HDU 4747 Mex 递推/线段树

会有一股神秘感。 提交于 2020-03-09 16:02:40
题目链接: acm.hdu.edu.cn/showproblem.php?pid=4747 Mex Time Limit: 15000/5000 MS (Java/Others)Memory Limit: 65535/65535 K (Java/Others) 问题描述 Mex is a function on a set of integers, which is universally used for impartial game theorem. For a non-negative integer set S, mex(S) is defined as the least non-negative integer which is not appeared in S. Now our problem is about mex function on a sequence. Consider a sequence of non-negative integers {ai}, we define mex(L,R) as the least non-negative integer which is not appeared in the continuous subsequence from aL to aR, inclusive. Now we want to

Interval GCD(线段树区间增加、区间查询)

被刻印的时光 ゝ 提交于 2020-03-09 15:27:16
题目描述 给定一个长度为N的数列A,以及M条指令 (N≤5*10^5, M<=10^5),每条指令可能是以下两种之一: “C l r d”,表示把 A[l],A[l+1],…,A[r] 都加上 d。 “Q l r”,表示询问 A[l],A[l+1],…,A[r] 的最大公约数(GCD)。 输入 第一行两个整数N,M,第二行N个整数Ai,接下来M行每条指令的格式如题目描述所示。 输出 对于每个询问,输出一个整数表示答案。 样例输入 5 5 1 3 5 7 9 Q 1 5 C 1 5 1 Q 1 5 C 3 3 6 Q 2 4 样例输出 1 2 4 算法提示: 我们知道gcd(x,y)=gcd(x,y-x)。它可以进一步扩展到三个数的情况:gcd(x,y,z)=gcd(x,y-x,z-y)。实际上,给性质对任意多个整数都成立。 因此,我们可以构造一个长度为N的新数列B,其中 B[i]=a[i]-a[i-1],B[1]可为任意值。数列B称为A的差分序列。 用线段树维护序列B的区间最大公约数。 这样一来,询问“Q l r”,就等于求出gcd(A[i],ask(1,l+1,r))。 在指令“C l r d”下,只有B[r+1]被减掉了d,所以在维护B的线段树上只进行两次单点修改即可。另外,询问时需要数列A中的值,可额外用一个支持“区间增加,单点查询”的树状数组对数列A进行维护。 完整代码:

hdu3973 AC's String 线段树+字符串hash

a 夏天 提交于 2020-03-08 19:37:03
题目链接: http://icpc.njust.edu.cn/Problem/Hdu/3973/ 题意是:给出一个模式串,再给出一些串组成一个集合,操作分为两种,一种是替换模式串中的一个字符,还有一种是查询模式串中[l,r]区间的字符串有没有出现在字符串集合中。 由于数据量很大,只能用O(nlogn)复杂度的算法才能通过,我们首先想到区间查询的操作线段树是可以做的,但是怎么样将一个子串唯一化呢?这就要说道字符串哈希了,我的做法是通过字符串哈希将字符串变成31进制数并且让它自然溢出,也就是对2^64取模。然后我们想到如何合并左右子区间呢?根据哈希的思想我们很容易想到:如果右区间的hash值为hash1,左区间的hash值为hash2,右区间的长度是len,则合并之后的hash=hash2*31^len+hash1,根据这样的策略可以知道任何区间的子串的hash值。 代码如下: 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned int ui; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define pf printf 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define

洛谷3372线段树模板题 对区间+k或者查询区间和

风流意气都作罢 提交于 2020-03-08 13:53:21
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned int ui; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define pf printf 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define prime1 1e9+7 9 #define prime2 1e9+9 10 #define pi 3.14159265 11 #define lson l,mid,rt<<1 12 #define rson mid+1,r,rt<<1|1 13 #define scand(x) scanf("%llf",&x) 14 #define f(i,a,b) for(int i=a;i<=b;i++) 15 #define scan(a) scanf("%d",&a) 16 #define dbg(args) cout<<#args<<":"<<args<<endl; 17 #define pb(i) push_back(i) 18 #define ppb(x) pop_back(x) 19 #define inf 0x3f3f3f3f 20 #define maxn 100005

115资源高清定制97601048薇█

。_饼干妹妹 提交于 2020-03-08 12:23:26
97601048薇█数据结构-线段树 参考资料 暂无 线段树是所有 RMQ 中最常用的数据结构。 功能:区间修改区间查询。不止最值、求和。只要可递推的值都可以构造线段树。 如果区间大小为 n,线段树有 cnt 个节点,那么 2n−1≤cnt<4n。 节点 对于每个节点 x,和堆类似,父亲节点为 x>>1(即 x/2 下取整的位运算方法,位运算方便而且快),左儿子为 x<<1(即 2x),右儿子为 x<<1|1(即 2x+1)。 同时每个节点对应一段区间,所以叫线段树。节点 1 对应的区间为 1∼n。设一个节点对应的区间为 l∼r,那么它的左儿子对应的区间就是 l∼mid,其中 mid=(l+r)>>1,右儿子区间为 mid+1∼r。如果一个节点对应单点区间,就没有儿子。 同时每个节点对应一个值,即该区间的 RMQ 值。如果是求最值问题,就表示该区间最大值;如果是求和问题,就表示该区间的和。 操作(单点修改区间查询) 一个线段树是求和还是求最值或者求别的东西,取决于 pushup(k) 函数,其中 k 为节点编号,时间复杂度 O(1)。 void pushup(int k){v[k]=max(v[k<<1],v[k<<1|1]);}//求最大值 根据原序列构造初始的线段树用 build() 函数,单点节点上的值就为单点的值,递归从下到上构造,时间复杂度 O(nlogn)。 void

高清115资源伽97601048薇█

偶尔善良 提交于 2020-03-08 12:21:32
97601048薇█数据结构-线段树 参考资料 暂无 线段树是所有 RMQ 中最常用的数据结构。 功能:区间修改区间查询。不止最值、求和。只要可递推的值都可以构造线段树。 如果区间大小为 n,线段树有 cnt 个节点,那么 2n−1≤cnt<4n。 节点 对于每个节点 x,和堆类似,父亲节点为 x>>1(即 x/2 下取整的位运算方法,位运算方便而且快),左儿子为 x<<1(即 2x),右儿子为 x<<1|1(即 2x+1)。 同时每个节点对应一段区间,所以叫线段树。节点 1 对应的区间为 1∼n。设一个节点对应的区间为 l∼r,那么它的左儿子对应的区间就是 l∼mid,其中 mid=(l+r)>>1,右儿子区间为 mid+1∼r。如果一个节点对应单点区间,就没有儿子。 同时每个节点对应一个值,即该区间的 RMQ 值。如果是求最值问题,就表示该区间最大值;如果是求和问题,就表示该区间的和。 操作(单点修改区间查询) 一个线段树是求和还是求最值或者求别的东西,取决于 pushup(k) 函数,其中 k 为节点编号,时间复杂度 O(1)。 void pushup(int k){v[k]=max(v[k<<1],v[k<<1|1]);}//求最大值 根据原序列构造初始的线段树用 build() 函数,单点节点上的值就为单点的值,递归从下到上构造,时间复杂度 O(nlogn)。 void

卖115资源的微信号

假装没事ソ 提交于 2020-03-08 12:11:49
数据结构-线段树 参考资料 暂无 线段树是所有 RMQ 中最常用的数据结构。 功能:区间修改区间查询。不止最值、求和。只要可递推的值都可以构造线段树。 如果区间大小为 n,线段树有 cnt 个节点,那么 2n−1≤cnt<4n。 节点 对于每个节点 x,和堆类似,父亲节点为 x>>1(即 x/2 下取整的位运算方法,位运算方便而且快),左儿子为 x<<1(即 2x),右儿子为 x<<1|1(即 2x+1)。 同时每个节点对应一段区间,所以叫线段树。节点 1 对应的区间为 1∼n。设一个节点对应的区间为 l∼r,那么它的左儿子对应的区间就是 l∼mid,其中 mid=(l+r)>>1,右儿子区间为 mid+1∼r。如果一个节点对应单点区间,就没有儿子。 同时每个节点对应一个值,即该区间的 RMQ 值。如果是求最值问题,就表示该区间最大值;如果是求和问题,就表示该区间的和。 操作(单点修改区间查询) 一个线段树是求和还是求最值或者求别的东西,取决于 pushup(k) 函数,其中 k 为节点编号,时间复杂度 O(1)。 void pushup(int k){v[k]=max(v[k<<1],v[k<<1|1]);}//求最大值 根据原序列构造初始的线段树用 build() 函数,单点节点上的值就为单点的值,递归从下到上构造,时间复杂度 O(nlogn)。 void build(int

115网盘资源更新

六月ゝ 毕业季﹏ 提交于 2020-03-08 12:02:37
数据结构-线段树 参考资料 暂无 线段树是所有 RMQ 中最常用的数据结构。 功能:区间修改区间查询。不止最值、求和。只要可递推的值都可以构造线段树。 如果区间大小为 n,线段树有 cnt 个节点,那么 2n−1≤cnt<4n。 节点 对于每个节点 x,和堆类似,父亲节点为 x>>1(即 x/2 下取整的位运算方法,位运算方便而且快),左儿子为 x<<1(即 2x),右儿子为 x<<1|1(即 2x+1)。 同时每个节点对应一段区间,所以叫线段树。节点 1 对应的区间为 1∼n。设一个节点对应的区间为 l∼r,那么它的左儿子对应的区间就是 l∼mid,其中 mid=(l+r)>>1,右儿子区间为 mid+1∼r。如果一个节点对应单点区间,就没有儿子。 同时每个节点对应一个值,即该区间的 RMQ 值。如果是求最值问题,就表示该区间最大值;如果是求和问题,就表示该区间的和。 操作(单点修改区间查询) 一个线段树是求和还是求最值或者求别的东西,取决于 pushup(k) 函数,其中 k 为节点编号,时间复杂度 O(1)。 void pushup(int k){v[k]=max(v[k<<1],v[k<<1|1]);}//求最大值 根据原序列构造初始的线段树用 build() 函数,单点节点上的值就为单点的值,递归从下到上构造,时间复杂度 O(nlogn)。 void build(int

省选模拟(35-40)

限于喜欢 提交于 2020-03-08 08:09:12
省选模拟35 1.two 线段树 对于给定的一条边,发现在另一棵树上的删边情况只有两种. \[dfn[u]<l\&\&dfn[v]\in[l,r]||dfn[u]\in [l,r]\&\&dfn[v]>r\] 所以把所有边二元组插到另一棵树的两棵线段树里(因为用的是ta的dfn序). 在第一颗线段树u处插v,第二颗v处插u. 查询时查询区间内线段树里一维 \(>l/<r\) 的所有. 可以用单调指针+pop_back搞. 删除后就打上懒标记防止重复计算. 实现起来如果想要简便一些需要一些脑子来优化. 2.bracket 点分治+FFT 第一次打点分治. 我们知道括号序列合法条件是前缀和始终 \(>=0\) . 可是还有神仙指出还有一种从后往前的判断方式:后缀最大值 来源: https://www.cnblogs.com/hzoi2018-xuefeng/p/12440901.html