支持单点修改区间求gcd##
因为(gcd)满足交换律和结合律,所以和维护区间和没什么区别……
支持区间修改区间求gcd##
因为求(gcd)有一个辗转相减法,所以有一个(gcd(a,b)=gcd(b-a,a)),推广到多个数也成立。具体证明在fsy神仙的博客里有写(转载的gsj学长的……)
所以对于这个序列维护一个差分数组(记为(sum)),这样区间加的时候只需把(d)加在(sum_l)上,再在(sum_r+1)上减一个(d)(中间的都抵消掉了),这样就把区间加转化成单点加了。查询的时候先查询(gcd(sum_{l+1},sum_{l+2},...,sum_r)),然后由于(sum_l=a_l-a_{l-1})所以对于这个要单独处理,但是由于你的修改可能打在了(sum)数组上,而又注意到(sum_1+sum_2+sum_3+...+sum_l=a_l),所以把(sum_1,sum_2,sum_3,...,sum_l)都加起来,(ans)就是这两个数求一个(gcd)。
具体的证明和细节可以去戳上面那个链接。
支持区间开方,单点加,区间求和##
值域只有1e9,这个范围内的数开个七八次方(或许还没有)就变成1了,所以维护一个区间最大值,如果区间最大值已经变成1了,就不用执行开方操作了,否则暴力开方即可。
Tips: 欧拉函数,取模函数和开方函数也有相同的特点
支持区间开方,区间加,区间求和##
这个用上面的办法会GG啊,数据卡满了要跑几分钟,所以考虑维护一个区间最大最小值,如果区间的极差(<=1),那么考虑如果开方之后的极差和开方之前的极差相等,就打上区间减标记,按区间减处理,其余按上面的处理。
权值线段树##
以权值为下标的线段树,当然你需要先把数据离散化
权值线段树求逆序对###
离散化数据之后一个一个插入线段树查询有多少比它大的即可
根据每个位置之前的逆序对个数还原原排列###
(这个好像和线段树没啥关系啊)对于给定序列进行差分,可以得到每个数在原序列中的排名。