[51Nod 1227] 平均最小公倍数 (杜教筛)

题目描述

∑ i = a b ∑ j = 1 i l c m ( i , j ) i \large\sum_{i=a}^b\sum_{j=1}^i\frac{lcm(i,j)}i i=abj=1iilcm(i,j)
1 < = a < = b < = 1 0 9 1 <= a <= b <= 10^9 1<=a<=b<=109

题目分析

这道题其实是[51Nod 1238] 最小公倍数之和题解的简化版,或者说是本质…
就直接上公式了

f ( n ) = ∑ i = 1 n l c m ( n , i ) n = ∑ i = 1 n i ( n , i ) \large f(n)=\sum_{i=1}^n\frac{lcm(n,i)}n=\sum_{i=1}^n\frac i{(n,i)} f(n)=i=1nnlcm(n,i)=i=1n(n,i)i,则 A n s = ∑ i = a b f ( i ) Ans=\sum_{i=a}^bf(i) Ans=i=abf(i)
f ( n ) = ∑ d ∣ n ∑ d ∣ i i d [ ( i , n ) = = d ] = ∑ d ∣ n ∑ d ∣ i i d [ ( i d , n d ) = = 1 ] = ∑ d ∣ n ∑ i = 1 ⌊ n d ⌋ i [ ( i , n d ) = = 1 ] = ∑ d ∣ n ∑ i = 1 d i [ ( i , d ) = = 1 ] \large f(n)=\sum_{d|n}\sum_{d|i}\frac id[(i,n)==d]\\=\sum_{d|n}\sum_{d|i}\frac id[(\frac id,\frac nd)==1]\\=\sum_{d|n}\sum_{i=1}^{\lfloor\frac nd\rfloor}i[(i,\frac nd)==1]\\=\sum_{d|n}\sum_{i=1}^di[(i,d)==1] f(n)=dndidi[(i,n)==d]=dndidi[(di,dn)==1]=dni=1dni[(i,dn)==1]=dni=1di[(i,d)==1]
此处有一个常识
∑ i = 1 n i [ ( i , n ) = = 1 ] = φ ( n ) n + [ n = = 1 ] 2 \sum_{i=1}^ni[(i,n)==1]=\frac {\varphi(n)n+[n==1]}2 i=1ni[(i,n)==1]=2φ(n)n+[n==1]

  • 证明如下
    • n > 1 n>1 n>1时,若 ( i , n ) = 1    ⟺    ( n − i , n ) = 1 (i,n)=1\iff(n-i,n)=1 (i,n)=1(ni,n)=1,所以与 n n n互质的数是成对出现,且他们的和为 n n n
    • 再加之 n = 1 n=1 n=1的特殊情况,可得
      ∑ i = 1 n i [ ( i , n ) = = 1 ] = φ ( n ) n + [ n = = 1 ] 2 \sum_{i=1}^ni[(i,n)==1]=\frac {\varphi(n)n+[n==1]}2 i=1ni[(i,n)==1]=2φ(n)n+[n==1]

继续
∴ f ( n ) = ∑ d ∣ n φ ( d ) d + [ d = = 1 ] 2 = 1 + ∑ d ∣ n φ ( d ) d 2 \large \therefore f(n)=\sum_{d|n}\frac {\varphi(d)d+[d==1]}2\\=\frac{1+\sum_{d|n}\varphi(d)d}2 f(n)=dn2φ(d)d+[d==1]=21+dnφ(d)d
∴ ∑ i = 1 n f ( i ) = n + ∑ i = 1 n ∑ d ∣ n φ ( d ) d 2 = n + ∑ d = 1 n φ ( d ) d ∑ d ∣ i 1 2 = n + ∑ d = 1 n φ ( d ) d ⌊ n d ⌋ 2 \large \therefore \sum_{i=1}^nf(i)=\frac{n+\sum_{i=1}^n\sum_{d|n}\varphi(d)d}2\\=\\\frac{n+\sum_{d=1}^n\varphi(d)d\sum_{d|i}1}2\\=\frac{n+\sum_{d=1}^n\varphi(d)d\lfloor\frac nd\rfloor}2 i=1nf(i)=2n+i=1ndnφ(d)d=2n+d=1nφ(d)ddi1=2n+d=1nφ(d)ddn
此时就可以用整除分块优化+杜教筛计算 ∑ d = 1 n φ ( d ) d \large \sum_{d=1}^n\varphi(d)d d=1nφ(d)d
h ( n ) = φ ( d ) d , g ( n ) = ∑ i = 1 n h ( d ) \large h(n)=\varphi(d)d,g(n)=\sum_{i=1}^nh(d) h(n)=φ(d)d,g(n)=i=1nh(d)
∵ n = ∑ d ∣ n φ ( d ) ∴ n 2 = ∑ d ∣ n φ ( d ) n = ∑ d ∣ n φ ( d ) d ⋅ n d = ∑ d ∣ n h ( d ) n d ∴ ∑ i = 1 n i 2 = ∑ i = 1 n ∑ d ∣ i h ( d ) i d = ∑ d = 1 n h ( d ) ∑ d ∣ i i d = ∑ d = 1 n h ( d ) ∑ i = 1 ⌊ n d ⌋ i \large\because n=\sum_{d|n}\varphi(d)\\\therefore n^2=\sum_{d|n}\varphi(d)n=\sum_{d|n}\varphi(d)d\cdot\frac nd=\sum_{d|n}h(d)\frac nd\\\therefore \sum_{i=1}^ni^2=\sum_{i=1}^n\sum_{d|i}h(d)\frac id\\=\sum_{d=1}^nh(d)\sum_{d|i}\frac id\\=\sum_{d=1}^nh(d)\sum_{i=1}^{\lfloor\frac nd\rfloor}i n=dnφ(d)n2=dnφ(d)n=dnφ(d)ddn=dnh(d)dni=1ni2=i=1ndih(d)di=d=1nh(d)didi=d=1nh(d)i=1dni
注意我们是在杜教筛,不能到这里就把 ∑ i = 1 ⌊ n d ⌋ i \sum_{i=1}^{\lfloor\frac nd\rfloor}i i=1dni看做 Θ ( 1 ) \Theta(1) Θ(1)可求的式子而之后再也不做变换,那样往往会陷入更麻烦的方法或者死胡同里去,接着往下
∴ ∑ i = 1 n i 2 = ∑ i = 1 n i ∑ d = 1 ⌊ n i ⌋ h ( d ) = ∑ i = 1 n i ⋅ g ( ⌊ n i ⌋ ) ∴ g ( n ) = ∑ i = 1 n i 2 − ∑ i = 2 n i ⋅ g ( ⌊ n i ⌋ ) \large\therefore \sum_{i=1}^ni^2=\sum_{i=1}^ni\sum_{d=1}^{\lfloor\frac ni\rfloor}h(d)=\sum_{i=1}^ni\cdot g({\lfloor\frac ni\rfloor})\\\therefore g(n)= \sum_{i=1}^ni^2-\sum_{i=2}^ni\cdot g({\lfloor\frac ni\rfloor}) i=1ni2=i=1nid=1inh(d)=i=1nig(in)g(n)=i=1ni2i=2nig(in)
然后套杜教筛即可

虽然在外面套了一层整除分块优化,但由于记忆化的原因,不影响时间复杂度,预处理出一部分 g g g后总复杂度为 Θ ( n 2 3 ) \large\Theta(n^{\frac 23}) Θ(n32)

…有兴趣的可以去了解一下[51Nod 1238] 最小公倍数之和题解,比这道题恶心点

AC code
#include 
#include 
#include 
#include 
#include 
using namespace std;
using namespace tr1;
typedef long long LL;
const int inv6 = 166666668;
const int inv2 = 500000004;
const int MAXN = 5e6 + 1;
const int mod = 1e9 + 7;
int Prime[MAXN], phi[MAXN], Cnt;
bool IsnotPrime[MAXN];
LL g[MAXN];
void init()
{
	phi[1] = 1;
	for(int i = 2; i < MAXN; ++i)
	{
		if(!IsnotPrime[i])
			Prime[++Cnt] = i, phi[i] = i-1;
		for(int j = 1; j <= Cnt && i * Prime[j] < MAXN; ++j)
		{
			IsnotPrime[i * Prime[j]] = 1;
			if(i % Prime[j] == 0) { phi[i * Prime[j]] = phi[i] * Prime[j]; break; }
			phi[i * Prime[j]] = phi[i] * phi[Prime[j]];
		}
	}
	for(int i = 1; i < MAXN; ++i)
		g[i] = (g[i-1] + 1ll * phi[i] * i % mod) % mod;
}
unordered_map<LL, LL> G;
inline LL sum1(LL i, LL j) { return ((i+j)%mod) * ((j-i+1)%mod) % mod * inv2 % mod; }
inline LL sum(LL n)
{
	if(n < MAXN) return g[n];
	if(G.count(n)) return G[n];
	LL ret = (n%mod) * ((n+1)%mod) % mod * ((2*n+1)%mod) % mod * inv6 % mod;
	for(LL i = 2, j; i <= n; i=j+1)
	{
		j = n/(n/i);
		ret = (ret - sum(n/i) * sum1(i, j) % mod) % mod;
	}
	return G[n]=ret;
}

LL solve(LL n)
{
	LL ret = n%mod;
	for(LL i = 1, j; i <= n; i=j+1)
	{
		j = n/(n/i);
		ret = (ret + ((sum(j)-sum(i-1))%mod) * ((n/i)%mod) % mod) % mod;
	}
	return ret * inv2 % mod;
}

int main ()
{
	LL a, b; init();
	scanf("%lld%lld", &a, &b);
	printf("%lld\n", ((solve(b)-solve(a-1)) % mod + mod) % mod);
}

你可能感兴趣的:(杜教筛)