总算是把动态求区间第k个数的算法看明白了。
在主席树的基础上,如果有修改操作,则要通过套树状数组来实现任意区间求第k小的问题。
刚开始看不明白什么意思,现在有一点理解。树状数组的每个元素是一个线段树,来维护修改后的前后缀和,树状数组能在log时间内更整个数组,现在用相同的方式更新整个线段树数组,每次更新一个点时,要更新这个点代表的整个线段树。同样的,求和时用一个use数组记录所要更新的点的下标,每次求不同线段树的同一位置的和。
静态初值不要用来初始化树状数组。
考虑到前缀和,我们通过树状数组来优化,即树状数组套主席树,每个节点都对应一棵主席树,那么修改操作就只要修改logn棵树,
O(nlognlogn+Mlognlogn)时间是可以的,但是直接建树要nlogn*logn(10^7)会MLE。
我们发现对于静态的建树我们只要nlogn个节点就可以了,而且对于修改操作,只是修改M次,每次改变俩个值(减去原先的,加上现
在的)也就是说如果把所有初值都插入到树状数组里是不值得的,所以我们分两部分来做,所有初值按照静态来建,内存O(nlogn),
而修改部分保存在树状数组中,每次修改logn棵树,每次插入增加logn个节点O(M*logn*logn+nlogn)。
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include
#include
#include
#include
#include
#include