抱怨:
真不应该直接去刚
(主席树:可持久化线段树)
,从中午12点学晚上到快7点,才理解,这不是我能刚的动的,为什么?因为学主席树之前要先学权值线段树,如果不了解权值线段树,直接刚主席树,根本不知道在说个啥玩意,效率很低
现在我讲一下权值线段树:
给一串数
1,2,3,1,5,4
很明显这串数的值域是[1,5]
,我们把值域二分为区间,求每一个区间有多少数,然后可以以通过这种方案来求:第k
大或者第k
小的数
第一步:
第二步:
第四步
权值线段树+二分离散化: 完整求不同值域区间含有数的数量
上面可能讲的不太细致,现在我们模拟一下过程来进行权值线段树讲解:
举一个栗子:假如我们要求
1 2 2 3 4 6
整个区间的第k
大,可以进行修改某个点。
这里说一下,为什么不用sort()
假如我们可以询问 n
次,每次询问分为查询和更改
如果用sort()
写最坏情况时间复杂度 O(n*nlogn)
,每次修改一次都需要排序,所以如果修改n-1
次查询1
次。呢么时间复杂度==O(n*nlogn)
,而权值线段树查第k
大的,只有O(n*logn),因为每次查询和更改的复杂度都是O(logn)
理解线段树之后,权值线段树其实就是把建树区间变为值域了,如果值域太大,而且数据量不是很大,呢么就离散化处理一下就ok了
离散化一下,当前的值域为1--n
建一个树,记录所有区间有多少个数,然后根据左右区间的大小和数量关系求取第k大即可
这是求取区间最大和最小,用权值线段树写的: