gcd的区间性质

博客探讨了GCD在区间内的单调性、反向包含性质及不同GCD的有限性,并通过例题展示了如何利用这些性质将计算复杂度从O(n^2)降低到O(nlogn),涉及二分查找和线段树等数据结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

gcd具有区间单调性:

对于gcd(l,r),l1<=l<=l2<=r2<=r<=r1,gcd(l2,r2)<=gcd(l,r)<=gcd(l1,r1)

gcd具有区间反向包含性质:

对于gcd(l,r),gcd(l1,r1),l<=l1<=r1<=r2,gcd(l,r)一定是gcd(l1,r1)的因子

区间内不同的gcd是有限的:

对于a【1】到 a【n】,设gcd【1,i】为a【1】到a【i】的gcd,则gcd【1,1】到gcd【1,n】中,至多存在log2n个不同的gcd值,这一点可以从gcd的反向包含性质中得出。
更进一步可以得出,gcd的变化是线性的。
也就是说,gcd【1,1】到gcd【1,k1】,gcd【k1+1,k2】…gcd【ki ,n】,每一段的gcd值是相等的
所以 ∑ i = 1 n \sum_{i=1}^n i=1ngcd【1,i】=gcd1 * len1 + gcd2 * len2 + gcd3 * len3 + … + gcdk*lenk
记为 ∑ i = 1 n \sum_{i=1}^n i=1ngcd【1,i】= ∑ i = 1 k \sum_{i=1}^k i=1kgcd【k】*len【k】
因为至多有log2 n个不同gcd值,所以上面计算的复杂度便从o(n)降低到了o(log2 n)

来看一道例题

https://ac.nowcoder.com/acm/contest/625/H
题目大意:求一段区间中所有连续子序列的gcd之和;
我们可以这样子变形: ∑ i = 1 n ∑ j = i n \sum_{i=1}^n\sum_{j=i}^n i=1nj=ingcd【i,j】= ∑ i = 1 n ∑ i = 1 k \sum_{i=1}^n\sum_{i=1}^k i=1ni=1kgcd【k】*len【k】
原来是对O(n^2)个gcd求和,现在转化为O(nlogn)个数求和
然而对于 ∑ j = i n \sum_{j=i}^n j=ingcd【k】*len【k】,我们并不知道分界点在哪,所以我们可以二分查找一段区间,对于gcd【c,l】,和gcd【c,r】我们查询gcd【c,m】,如果gcd【c,m】和某端点值相等的话,那么这一整段区间的值都是相同的,这里不加证明的给出这种计算的复杂度log(1e9)logn,然后我们查询可以用线段树维护,查询提供一个logn,加上n次计算 ∑ j = i n \sum_{j=i}^n j=ingcd【k】*len【k】,一共是n(log^3)的算法复杂度,但这不是严格边界。
其中的log(1e9)logn很容易退化,这里数据不强应该能过

还没试过,有空试试看哈哈,只是自己想的一种办法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值