线段树
文章平均质量分 56
_kikyou-
这个作者很懒,什么都没留下…
展开
-
Codeforces Round #757 E. Divan and a Cottage(非递减权值线段树+标记永久化)
传送门给出了n天的室外温度t[i],同时规定,如果第i天早上的室内温度为P,那么当t[i]>P,第i+1的室温变为P+1,如果小于,则变为P-1,等于则仍然是P。按照样例解释一下输入的信息:首先输入n,代表有n天,接下来是n组信息,代表每天的室外温度以及询问每组信息由室外温度t、询问个数k、k个询问组成。对于第i组信息,首先给出室外温度t[i],然后给出k,接下来是k个询问,每个询问是一个非负数x[j],表示如果第一天早上的室温是x[j],那么第i天结束后,室温是多少? 比如第三组信息,首原创 2021-12-06 20:48:22 · 613 阅读 · 0 评论 -
2020ccpc威海 G.Caesar Cipher (hash+线段树)
传送门给定了一个长度不超过5e5的序列,0<=a[i]<65 536,q次操作,q不超过5e5。操作1:[l,r]区间每个数加1,并且对65536取模操作2:给出x,y,L,询问[x,x+l-1] ,[y,y+l-1]两个区间的序列是否相等。这题区间修改是每次加1,一共最多加nq,所以我们取模可以写成单点修改,最多取模(n*q)/65536 次,(通过维护区间最大值剪枝实现这个暴力的单点修改。)我们不考虑取模,发现这题是可以用hash+线段树写的。假设hash进制为base,令p原创 2021-11-20 21:57:15 · 470 阅读 · 0 评论 -
【HDU - 4348】To the moon (主席树 标记永久化区间更新)
传送门主席树的修改一般是只涉及单点修改的,因为区间操作如果我们pushdown的话,相当于又涉及了两个孩子节点的修改,一直递归下去,这样空间要去就和建n棵线段树差不多一个量级了。我们可以把懒标记永久打在节点上,不下传,只在pushup和查询的时候用上。具体来说,pushup的时候除了合并左右子节点,再考虑一下根节点区间的懒标记的影响。查询的时候,查询路径上经过节点的懒标记都要合并起来,一路记录下去,最终在查询区间进行计算。#include<bits/stdc++.h>using na原创 2021-11-13 20:25:09 · 359 阅读 · 0 评论 -
D. Persistent Bookcase (可持久化线段树维护bitset)
传送门给定一个n*m的矩阵,每个元素都是0或1,一共4种操作,操作q次。1、把(i,j)改成12、把(i,j)改成03、翻转第i行4.回溯变成第k次操作时的矩阵每次操作完后输出矩阵所有元素之和。(1<=n,m<=1000,q<=1e5)涉及回溯历史版本,可持久化线段树。我们把每行看成一个整体,单独一行涉及的操作是单点修改,区间反转,查询区间和,如果我们对每行都建线段树,即:用线段树维护n棵线段树之和,那么肯定会爆空间的。单点修改,区间反转,查询区间和我们可以用一个空间位原创 2021-11-13 16:20:20 · 303 阅读 · 0 评论 -
2019 ICPC 南昌 Regional K. Tree(树上启发式+动态开点线段树)
传送门给定了一棵带点权的有根树,求出节点对(i,j)的个数,满足a[i]+a[j]=2*a[lca]原创 2021-11-12 20:55:19 · 121 阅读 · 0 评论 -
Codeforces Round #373 C. Sasha and Array(斐波那契数列矩阵形式+矩阵快速幂+线段树)
传送门题意,给定一个序列,定义f(a)表示斐波那契数列的第a项,序列涉及两种操作,一是区间每个数加x二是对于询问[l,r],输出 Σf(a[i]) (l<=i<=r),对1e9+7取模。看到斐波那契数列容易联想到其矩阵形式:[f(3)(f2)]=[f(2)f(1)]∗[1110]\begin{bmatrix}f(3)&(f2)\end{bmatrix}=\begin{bmatrix}f(2)&f(1)\end{bmatrix}*\begin{bmatrix}1&a原创 2021-11-09 20:47:28 · 940 阅读 · 0 评论 -
D. Bash and a Tough Math Puzzle (线段树+dfs剪枝)
传送门给定序列,单点修改,区间询问[l,r]中,能否最多修改一个数使得区间GCD等于x。(询问时的修改只是想象中的修改,不会改变序列的元素)线段树维护区间gcd这个很显然了,问题是询问如何处理呢?刚开始的方向是找满足条件的序列,有什么规律性质,但是在纸上画了很久也没有结果。可以说方向完全错了。...原创 2021-11-08 23:34:54 · 82 阅读 · 0 评论 -
Lawn of the Dead (线段树)
传送门给定一个n*m的网格,有k个地雷,不能踩到地雷所在格子,从(1,1)出发,只能往左或者往下走,问最多可以到达多少个格子。由于n,m都是1e5级别,所以我们不能模拟。我们先观察一个结论,对于第i行,假设有y1,y2两个雷,[y1+1,y2-1]这个区间格子如何能被到达呢?只能从上面下来,所以我们在第i-1行中找打[y1+1,y2-1]这个区间内最左端的可到达的位置idx,那么第i行的[idx,y2-1]这个区间都是可到达的了。如果我们用1代表可到达,0代表不可到达,上面的操作实质原创 2021-11-06 17:25:01 · 395 阅读 · 0 评论 -
Codeforces Round #200 D. Water Tree(树剖+线段树 / 线段树+思维)
传送门给定有根树,初始点权为0,有三种操作:1、u为根的子树全部节点赋值为12、u到根节点1的路径上,所有的点赋值为03、查询u的点权带点权的树上路径修改问题,可直接树剖暴力写完。同时,树剖还可以解决这个问题的拓展:点权并非只有1,0两种,可以是任意值,同样是区间修改+区间查询。时间复杂度O(N logN log N)#include<bits/stdc++.h>using namespace std;//#pragma GCC optimize(2)#define ul原创 2021-11-05 15:56:46 · 117 阅读 · 0 评论 -
D. Integers Have Friends (思维+区间gcd)
传送门给定正整数序列,每个数都不一样,求最长的子段[l,r],满足a[l] % m = a[l+1] % m ... = a[r] % m , m>=2从这个式子观察得到一个性质,如果[l,r]区间满足条件,那么a[l+1]-a[l],a[l+2]-a[l+1]一定是m的倍数,即:差分数组一定是k1 * m,k2 * m…的形式,ki是整数,这个性质等价为[L,R]区间对应的差分数组的GCD大于等于2 。而且我们发现,符合条件的区间长度是具有单调性的,我们可以二分这个长度,然后枚举+验原创 2021-11-04 23:29:46 · 183 阅读 · 0 评论 -
Codeforces Round #312 E. A Simple Task (桶排序思想+线段树维护桶)
传送门给定一个只包含小写字母的字符串,长度为n,m次操作,每次指定 [L,R] K K=0,让[L,R]区间降序排列,否则升序排列。输出最终字符串。由于每个数都相当于是[0,25]区间内,我们试试能不能开26个桶,第i个桶记录有多少个i,利用桶排序来求解。我们开n个桶,每个桶大小都是26,记录第i位的26个数分布情况。线段树维护桶序列,每个节点表示:当前区间内,桶合并后的情况,即:【0,25】这些数各有多少个。于是每次操作就可以这样处理:先区间查询出当前询问区间[L,R]里面,【0,25原创 2021-11-04 19:38:34 · 116 阅读 · 0 评论 -
Codeforces Round #737 (Div. 2)D. Ezzat and Grid (dp+线段树)
传送门给了n个01串,每个串都是1e9的长度。一个01串集合是优美的当且仅当相邻的任意两个串中,至少存在一列,满足在这两个串里面都是1。问最少删去多少个串,才能使得剩下的串构成一个优美集合。题目等价于可以从中挑出多少个串,使得任意相邻的两个串都满足条件。我们先思考一个暴力解法:dp[i]表示前i个串中,最多可以挑出多少个串构成优美集合。求解dp[i]:先枚举串i的每一个1的位置j,然后枚举dp[k],(1<=k<=i-1),对于j位置上也是1的串k,我们取dp[i]=max(d原创 2021-11-03 23:40:01 · 144 阅读 · 0 评论 -
Educational Codeforces Round 112 E. Boring Segments(双指针+线段树)
传送门给定一个[1,m]区间的坐标轴n条线段,每个覆盖[li,ri]的区间并有一个价值w[i],我们可以从点u 到达点v 当且仅当u v在同一个线段中,现在要选取一个代价最小的线段集合,使得我们可以从1到达m。 线段长度大于1。代价指:所选取线段集合中w[i]最大值与最小值之差。保证一定有解。线段覆盖区间的问题,我们可以让右端点-1,然后区间加1,那么最终区间不为0的连续段,就可以任意跳了。 比如 [1,7] [8,9] 这两个线段是不相交的,右端点-1,变成[1,6] [8,8] ,做完区间加原创 2021-11-03 21:30:31 · 111 阅读 · 0 评论 -
Educational Codeforces Round 81 E. Permutation Separation(dp+线段树优化)
传送门题意:给定一个排列p,每个位置有一个花费a[i],先可以在任意位置把p切开成头尾两部分,非空,然后从两个部分中选几个数放到另一个部分,使得左边集合的每个数都小于右边集合的最小值(某个集合为空也符合要求)。 移动第i个数花费为a[i],求最小花费。(1<=n<=2e5)我们观察发现,最终两个集合的答案只能是这样 1 2...m ; m+1,m+2..n于是,我们可以枚举分割点t(t在左边),再枚举左边集合的最大值m,[1,t]中找到大于m的元素给他们移到右边去,[t+1,n原创 2021-10-26 20:15:59 · 135 阅读 · 0 评论 -
HDU 6959 zoto (莫队+树状数组)
传送门题意本质就是,给定序列,m次询问,每次问[x1,x2]这个区间内的数中,大小位于[y1,y2]这个区间的不同的数有多少个。求区间不同的数的加强版 。求区间不同的数的时候,我们只需要维护1个桶,记录每个数出现多少次即可,用一个变量ret保存答案,这里我们需要对每个数都分别保存答案,可以用权值线段树或树状数组维护 。单点修改,区间查询。时间复杂度是O(Nsqrt(N)logN) 但是跑不满,因为不一定每次都要修改。1900ms。注意我们把y的坐标都加了1,保证树状数组维护的定义域是从1开始。原创 2021-10-24 21:03:02 · 116 阅读 · 0 评论 -
2019-2020 ICPC, Asia Jakarta Regional Contest K. Addition Robot(线段树维护矩阵乘积)
传送门给定了只含字符A B的字符串,操作1是区间翻转A变成B,B变成A,操作2是区间执行上述操作,输出结果(A,B) 。原创 2021-10-11 23:26:14 · 162 阅读 · 0 评论 -
牛客练习赛81 D 小 Q 与树 (权值线段树+dsu on tree)
tp链接min(a[u],a[v])*dis(u,v)这个式子带min函数,dis函数,都比较麻烦,肯定需要化简的。trick:dis(u,v)可以引入LCA,转化成dis(1,u) + dis(1,v) - 2*dis(1,LCA)分类讨论,在rt子树中,把点权大于等于a[rt]的节点分一类,小于a[rt]的节点分一类于是可以把式子写成:对于ax1,ax2,...axcnt1>=aua_{x1},a_{x2},...a_{xcnt1} >= a_{u}ax1,ax2,..原创 2021-10-11 15:17:35 · 167 阅读 · 0 评论 -
D. Tree and Queries (dfs序+莫队 /树上启发式合并)
传送门可以离线,子树查询,数据范围是1e5,妥妥的莫队水题。全局维护num[i]表示颜色i出现的次数,cnt[i]表示出现次数大于等于i次的颜色种类数。当新加入颜色x,cnt[num[x]+1]+1,num[x]+1当减去颜色x,cnt[num[x]]-1 ,num[x]-1,代码略。如果考虑用树上启发式,我们同样维护num[i],cnt[i],含义一样。当然如果用cnt[i]表示出现次数恰好等于i次的颜色种类数,那么每次查询都是区间查询,需要对cnt这个桶,建线段树维护。#include原创 2021-10-03 22:13:02 · 244 阅读 · 0 评论 -
CF1009F Dominant Indices (树上启发式合并维护线段树+常数优化)
传送门给定有根树,定义d[x,i]表示以x为根的树中,与x的距离为i的节点个数,对于每棵子树,求出使得d[x,i]最大的i,存在多个输出最小的。其实是一道dsu on tree的模板题了…正解:cnt[i]表示当前子树深度为i的节点个数,每次更新都是用的当前子树的节点进行更新,所以可以直接用全局变量维护最大值,然后更新就行。但是这题卡常,刚开始add函数是用递归写的,就t了,改成dfs序很快就跑完了。递归:dfs序:#include<bits/stdc++.h>using n原创 2021-10-03 16:01:31 · 173 阅读 · 0 评论 -
CF960F Pathwalks (线段树优化图上的LIS)
传送门题意:给定无向图,带边权,n个顶点m条边,找到一条最长的路径满足,经过的边边权严格递增,边的编号也严格递增(编号即输入的顺序),最长的定义是边的条数最多。(1<=n<=1e5,1<=m<=1e5)相当于把LIS问题放到了图上,我们按边的输入顺序进行更新答案。我们对每个顶点维护一个权值线段树,(就像用权值线段树维护LIS一样),定义域是边权,值就是这个以边权结尾的路径的最长长度,维护区间最大值。对于边(u,v,w),我们在u的线段树里面查询[0,w-1]最大值M,v原创 2021-09-14 15:16:06 · 148 阅读 · 0 评论 -
SPOJ GSS 线段树系列
目录文章目录目录[SP1043 GSS1 - Can you answer these queries I](https://www.luogu.com.cn/problem/SP1043)[SP1716 GSS3 - Can you answer these queries III](https://www.luogu.com.cn/problem/SP1716)[SP2713 GSS4 - Can you answer these queries IV](https://www.luogu.com.原创 2021-09-07 23:37:34 · 299 阅读 · 1 评论 -
HDU7059 +HDU7116 (线段树暴力修改)
HDU7059 传送门给了两种修改:操作1就是区间每个数减去自己的lowbit,由于a[i]是不超过int型范围的,所以操作1最多进行32次,可以单点暴力修改,同时记录这个区间是否都是0,用于剪枝操作2是区间每个数加上highbit,其实也就是最高位的贡献乘2,我们考虑把最高位与其他位分开维护区间和。 这样操作2就乘了区间乘某个数了,经典的线段树维护操作。具体要存的信息就是:1、二进制下最高位之和 ,涉及区间乘22、其余位之和,涉及单点暴力修改3、区间是否都是0,用于剪枝,如果都原创 2021-09-06 23:20:23 · 209 阅读 · 0 评论 -
F. Please, another Queries on Array? (线段树维护区间积的欧拉函数)
传送门给定序列,两种操作,区间每个数乘v,求区间积(对1e9+7取模)后的欧拉函数。序列每个数以及v都不超过300。首先bd得到欧拉函数的计算公式:首先序列每个数不超过300,v也不超过300,300以内的质数很少,打表发现只有62个,这个信息显然很有用。区间欧拉函数就是区间积,很明显可以用线段树维护 。 质因子项我们可以预处理+逆元得到,用f[i]表示第i个质数p[i]的 (p[i]-1)/p[i] % mod关键是x在乘完之后要取模,取模后求的质因子肯定是错了的,所以我们维护区间积的同原创 2021-08-29 17:15:20 · 255 阅读 · 0 评论 -
Codeforces Round #731 (Div. 3) (E (dp) + F(二分+st表) + G(dfs判环) )
E. Air Conditioners(dp)对于第i个格子,如果我们单独考虑其右边的所有空调(包括第i格的空调,如果有的话),那么可以通过dp解决。r[i]=min(c[i],r[i+1]+1) r[i]表示i以及i右边的空调影响下,i位置的最低温度。同理可以求出l[i] ,那么第i个位置的答案就是min(l[i],r[i])#include<bits/stdc++.h>using namespace std;//#pragma GCC optimize(2)#define l原创 2021-08-07 21:08:18 · 152 阅读 · 0 评论 -
Educational Codeforces Round 112 (Rated for Div. 2) (A+B+C+D+E)
ABCD思维 E双指针+线段树优化[A. PizzaForces](https://codeforces.com/contest/1555/problem/A)[B. Two Tables](https://codeforces.com/contest/1555/problem/B)[C. Coin Rows](https://codeforces.com/contest/1555/problem/C)[D. Say No to Palindromes](https://codeforces.com/co原创 2021-08-03 16:27:51 · 606 阅读 · 0 评论 -
Codeforces Round #225 (Div. 1) C. Propagating tree (线段树+dfs序)
传送门原创 2021-05-21 11:55:23 · 135 阅读 · 1 评论 -
VK Cup 2015 - Qualification Round 1 D. Closest Equals (线段树离线 / 主席树)
传送门题意:给定长度为n的序列,q次询问,每次询问[l,r]区间内满足a[x] == a[y]最近的x y,定义距离为|x-y|,输出这个距离。如果不存在两个相同的元素则输出-1.不强制在线。(1<=n,q<=5e5)分析:首先我们考虑对于右端点固定的区间[1,r],如何用线段树进行查询?我们可以用p[i]表示a[i]上一次最近出现的位置。求出p数组后,如果我们让v[i]表示|i-p[i]|,那么会出现一个情况就是询问[l,r]区间的时候,某个数的p[]在l左边,但是影响了答原创 2021-05-20 16:51:10 · 289 阅读 · 0 评论 -
Codeforces Round #305 (Div. 1)E. Mike and Friends(AC自动机+fail树dfs序+主席树)
传送门题意:给定n个字符串,q次询问,每次给出正整数L,R,X,要求输出第x个字符串在第l个字符串到第r个字符串的总匹配次数。(字符串长度之和不大于2e5)分析:首先我们考虑对于一个字符串集合,我们如何求出其中某个字符串在集合中的匹配次数?比如给定集合cacaa,baabaa,aa。求出aa在集合中的总匹配次数。(易知答案是4) 。 我们可以把所有的串插入AC自动机,再用aa去trie树上匹配,随后统计fail树上每个子树的点权和。 aa的尾节点的匹配次数就是答案了。 为什么呢?因为在fail树原创 2021-05-12 11:05:30 · 197 阅读 · 0 评论 -
Codeforces Round #719 (Div. 3) F2. Guess the K-th Zero (Hard version) (交互题+线段树)
题目链接题意:给定了一个长度为n的 只有0/1组成的数列,给出t行,每行给出一个整数k,可以询问若干次区间和,然后输出第k个0所在的位置下标。 总的询问次数不超过6e4。每次输出结果之后把第k个0改成1。(1<=t<=1e4 , 1<=n<=2e5 保证第k个0一定存在。 )分析:首先可以想到二分,但是这里又涉及单点修改。所以可以用线段树来维护区间和。 可以用数组vis[i]标记以i为根的区间的区间和是否已知。 细节见代码#include<bits/stdc++.原创 2021-05-07 21:20:20 · 184 阅读 · 0 评论 -
2021-M-Stone Games(思维+主席树)
题目链接题意:给定了n堆石子每堆的数量是[1,1e9]的整数,q次询问,每次给出区间[l,r],可以选择[l,r]区间的石子堆加起来凑出一个数x,问最小的无法被凑出的数是多少?(每次询问中,每堆石子最多选择1次,此题强制在线)分析:对于[l,r]区间,我们把石子数放进一个桶里。首先0肯定可以被凑到,因为可以每堆都不选。此时我们关心1是否能被凑到,我们查询桶内 值在[0,1]区间的数的和,假设和为x,(也就是有x个1), 那么说明我们可以凑出[0,x]区间的所有数(当然,如果此时x的值是0,那原创 2021-05-06 15:23:10 · 135 阅读 · 0 评论 -
CF1004F Sonya and Bitwise OR (线段树+暴力区间合并)
题目链接题意 :给定序列a , q次操作,包括单点修改和区间询问, 每次询问一个区间[l,r]内 ,有对少对[L,R]满足a[L,R]所有数的按位或运算结果不小于给定的x 。分析:序列a的每个数都小于2^20。那么每个区间的前缀(以及后缀) 扫过去进行或运算,显然这个过程中结果会不断增大,但是结果变化不会超过20次。 所以我们可以用一个vector记录前缀(以及后缀)扫描过程中或运算的结果以及个数 。(显然vector中的元素大小是递增的)所以我们用线段树维护三个信息,区间答案、前缀或运算情况、后原创 2021-03-17 23:12:18 · 184 阅读 · 0 评论 -
P3567 [POI2014]KUR-Couriers (主席树+暴力)
添加链接描述服了自己,主席树也学了有一段时间了,被一个板题卡住了。说到底还是没有理解线段树在区间查询时二分的思想。#include<bits/stdc++.h>using namespace std;#define ll long longconst int maxn = 5e5+5;const int mx = 50;const int mod = 1e9+5;const ll inf = 34359738370;const int INF = 5e5+1;//给定序列原创 2021-03-16 18:45:48 · 130 阅读 · 0 评论 -
One Occurrence CodeForces - 1000F (思维+主席树)
题目链接题意:给定序列a ,q次询问 每次询问要求[l,r]区间任意一个只出现过一次的数 没有则输出0 。分析:这题和这题十分类似,我们先分析对于右端点固定的区间,求出[1,r]内任意的[l,r]区间只出现过一次的数。我们用last[i]维护i上一次出现的位置,那么对于序列last[a[i]](i映射成last[a[i]]),我们查询[l,r]内是否存在只出现过一次的数就等价于last[a[i]]在[l,r]区间是否存在小于l的值, 根据贪心我们可以用线段树维护序列last[a[i]]的区间最小原创 2021-03-15 10:19:49 · 207 阅读 · 0 评论 -
Tufurama CodeForces - 961E (思维+主席树)
题目链接题意:一个电视剧有n季,每季有a[i]集,当x!=y,存在一对第x季第y集与第y季第x集冲突,(前题是a[x]>=y,a[y]>=x) 。问这个电视剧一共有多少对冲突。分析:首先如果某季的集数大于n,我们直接让他等于n。再把这题抽象一下,大概就是让我们求出 ,对于每个下标i,有多少个下标j满足i<j<=a[i],且a[j]>=i,也就是对每个a[i]>i的下标i,求出序列a的[i+1,n]区间内有多少个数的大小属于[i,n]区间内, 这样看来就是主席树模原创 2021-03-13 17:19:19 · 173 阅读 · 0 评论 -
Just $h$-index HDU - 6278 (二分+主席树)
题目链接题意:给定序列a,q次询问,每次询问区间[l,r]中最大的h,使得h满足序列a的[l,r]区间内不小于h的数至少有h个。分析:可持久化权值线段树 ,二分这个答案, 每次验证都是区间查询。(查询root[r]-root[l-1]这棵树维护的桶中 ,[mid,INF]中数的个数是否大于等于mid)#include<bits/stdc++.h>using namespace std;#define ll long longconst int maxn = 1e5+7;const原创 2021-03-13 16:15:03 · 85 阅读 · 0 评论 -
D-query SPOJ - DQUERY (主席树入门)
题目链接题意:给定序列a,给出q次区间询问,每次询问[l,r]区间内有多少个不同的数。分析:我们先分析对于固定的区间[1,n],如何利用线段树统计[l,n]不同的数?我们用线段树记录区间内不同数的个数(这里不是用权值线段树,而是普通地对定义域建树)。开始是一棵空树,我们扫描数组并单点修改,如果当前的数a[i]在之前没有出现过,那么直接使线段树的pos==i处的值为1, 如果之前出现过,我们就把之前出现位置的值变成0,当下出现位置的值变成1 。这样的目的就是使得统计的时候每个数在最右边出现的.原创 2021-03-13 15:20:42 · 237 阅读 · 0 评论 -
Find the answer HDU - 6609 (二分+权值线段树+离散化)
题目链接题意:给定序列 和正整数m,询问对于每个下标i ,至少需要让前面多少个数变成0才可以使得到前缀和pre[i]小于等于m.思路:建权值线段树,维护桶内元素个数以及元素和。我们可以二分变成0的元素个数,每次查询桶内取mid个数的最大和(假设为mmax),然后验证pre[i]-mmax<=m就可以。PS:这题我一开始建树是动态开点,时间复杂度是O(nlogn*logINF) 没想到tle了 …后面改成离散化建树,时间跑了2300ms左右#include<bits/stdc++.原创 2021-03-12 14:52:21 · 137 阅读 · 0 评论 -
K-th Closest Distance HDU - 6621 (二分+主席树)
题目链接题意:给定序列,给定m次询问,每次询问提供4个数l,r,p,k查询[l,r]内和p大小相差第k小的距离数值。 (也就是相减得到的绝对值里面,第k小的数)分析:我们就拿上面这个例子,把数先画到坐标轴上↓对于询问的区间[l,r]内所有的数,我们可以从0开始枚举和p的距离,同时统计当前枚举囊括的数,当某次枚举包括进了>=k个数,那么答案就找到了 。很显然上述枚举过程可以优化成二分查找 。每次就相当于要求出询问询价内有多少个数属于[p-mid,p+mid] ,这不就是和主席树求区间第k原创 2021-03-11 22:58:57 · 86 阅读 · 0 评论 -
P3834 【模板】可持久化线段树 2(主席树)
题目链接静态查询区间第k小问题。我们可以先联想权值线段树查询[1,n]整体区间第k小问题的思路:权值线段树本质是一个桶,左子区间桶内的数大于等于k就递归给左子树查询,否则递归给右子树查询第k-tree[ lc[rt] ]小的值 。虽然这题是查询[l,r]区间第k小,但是我们可以转化成整体区间第k小问题:由于数据范围太大,我们先把数据离散化,对离散化后的数组的每个前缀建线段树,维护离散化数组中的数在原数组中出现的次数之和。(本质就是个桶)那么[l,r]区间内的第k小值就等于 :[1,r]区间对原创 2021-03-11 15:43:10 · 292 阅读 · 0 评论 -
P3919 【模板】可持久化线段树 1
可持久化线段树入门参考博客题目链接主席树单点修改的个人理解:主席树本质是一个线段树森林,但是利用共享孩子节点这一思想节约了大量的建树空间与时间。每次修改就相当于对修改后的数组重新建一棵线段树,但是由于单点修改只会影响左右子树中的某一个,所以另外一个不被影响的子树就直接继承被修改版本的线段树,被影响的子树就新造一条总长度为logn的链。所以主席树是必须动态开点的,而且需要开一个数组来保存每个版本的根节点序号。#include<bits/stdc++.h>using namespac原创 2021-03-11 14:27:10 · 83 阅读 · 0 评论