线段树基本操作

本文探讨了在数据结构中使用线段树解决区间修改和查询问题的多种方法,包括支持单点修改区间求gcd、区间开方、单点加、区间求和等操作,同时介绍了权值线段树在求逆序对和还原原排列的应用。

支持单点修改区间求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\),那么考虑如果开方之后的极差和开方之前的极差相等,就打上区间减标记,按区间减处理,其余按上面的处理。

权值线段树

以权值为下标的线段树,当然你需要先把数据离散化

权值线段树求逆序对

离散化数据之后一个一个插入线段树查询有多少比它大的即可

根据每个位置之前的逆序对个数还原原排列

(这个好像和线段树没啥关系啊)对于给定序列进行差分,可以得到每个数在原序列中的排名。

转载于:https://www.cnblogs.com/kma093/p/10325685.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值