Small GCD
有两种做法
第一种做法:欧拉反演(其实我赛时的时候是想到了欧拉反演的,但是我不太清楚欧拉反演的使用trick)
欧拉反演的trick见这篇文章
欧拉反演直接用在gcd上还是挺多的(就像这篇文章中说的,gcd求和就可以用欧拉反演,实际上“龙哥的问题”就是典型的欧拉反演),可以想一下\(cnt\)数组怎么求
\(cnt\)数组其实是只用记一维的(因为记两维肯定爆炸了)。考虑对于\(d\),如果\(d\)不是\(a_i\)的约数,那么\(d\)在\(i\)的\(cnt\)和\(d\)在\(i-1\)的\(cnt\)肯定是一样的;如果\(d\)是\(a_i\)的约数,那么\(d\)在\(i\)的\(cnt\)就多了\(1\)
第二种做法:考虑贡献
见这篇文章
由于这道题目给的序列是离散的,我们没办法利用欧拉函数,所以考虑贡献的时候只能求出前面有多少个\(a_i\)满足gcd是\(x\),那么\(x\)肯定是\(a_i\)的约数,但是这样的\(a_i\)与\(a_j\)的gcd却不一定是\(x\),但是我们有结论,公约数一定是gcd的约数,所以我们用容斥减去更大\(g\)就好了
update 2026.3.2
对第二个题解的解释
首先将\(\{a\}\)排序不会影响答案,所以先排序
排序之后可以知道,对于\(a_j\),假设我们计算出了\(\sum_{i=1}^{j-1}\gcd(a_i,a_j)\),那么\(a_j\)对答案的贡献就是\((n-j)\times\sum_{i=1}^{j-1}\gcd(a_i,a_j)\)
考虑计算上面这个和式,考虑贡献,即设\(x=\gcd(a_i,a_j)\),固定\(x\)的情况下,考虑这样的\((a_i,a_j)\)对的个数
如果我们在循环完\(1\sim j-1\)的时候,求出了\(\forall x\),约数有\(x\)的\(a_i\)的个数,我们会发现还不够,因为对于这样的\(a_i\),不一定有\(\gcd(a_i,a_j)=x\),但是一定有\(x|\gcd(a_i,a_j)\),所以就可以像题解那个样子进行容斥原理了

浙公网安备 33010602011771号