51nod1584 加权约数和 (莫比乌斯反演)

传送门

如果求出 f ( n ) = ∑ i ∑ j ≤ i i ∗ σ ( i j ) , g ( n ) = ∑ i i ∗ σ ( i 2 ) f(n)=\sum_i\sum_{j\le i}i*\sigma(ij),g(n)=\sum_i i*\sigma(i^2) f(n)=ijiiσ(ij),g(n)=iiσ(i2)
那么 2 ∗ f ( n ) − g ( n ) 2*f(n)-g(n) 2f(n)g(n) 就是答案

有一个结论是
σ 0 ( i j ) = ∑ d ∣ i ∑ l ∣ j [ g c d ( d , l ) = 1 ] \sigma_0(ij)=\sum_{d|i}\sum_{l|j}[gcd(d,l)=1] σ0(ij)=dilj[gcd(d,l)=1]
证明(口胡):考虑某一个质因子 p p p,假设最后在约数中为 p c p^c pc
令如果 p p p i i i 中为 p a p^a pa,如果 c ≤ a c\le a ca 那么我们在 i i i 中填上 c c c,否则在 j j j 中填上 c − a c-a ca
显然 p p p 只会在一边出现而且所有的因数考虑完了
如果是 σ ( i j ) \sigma(ij) σ(ij) 的话考虑一下上面的过程想一想最后是什么数,有:
f ( n ) = ∑ i = 1 n i ∑ j = 1 i ∑ p ∣ i ∑ q ∣ j [ g c d ( p , q ) = 1 ] p j q f(n)=\sum_{i=1}^ni\sum_{j=1}^i\sum_{p|i}\sum_{q|j}[gcd(p,q)=1]\frac{pj}{q} f(n)=i=1nij=1ipiqj[gcd(p,q)=1]qpj
= ∑ d = 1 n μ ( d ) ∑ d ∣ p p ∑ p ∣ i i ∑ d ∣ q ∑ d ∣ j , j ≤ i j q =\sum_{d=1}^{n}\mu(d)\sum_{d|p}p\sum_{p|i}i\sum_{d|q}\sum_{d|j,j\le i}\frac{j}{q} =d=1nμ(d)dpppiidqdj,jiqj
= ∑ d = 1 n μ ( d ) ∑ p = 1 n / d d p ∑ p ∣ i , i ≤ n / d d i ∑ q ≤ i ∑ q ∣ j , j ≤ i j q =\sum_{d=1}^{n}\mu(d)\sum_{p=1}^{n/d}dp\sum_{p|i,i\le n/d}di\sum_{q\le i}\sum_{q|j,j\le i}\frac{j}{q} =d=1nμ(d)p=1n/ddppi,in/ddiqiqj,jiqj
= ∑ d = 1 n μ ( d ) d 2 ∑ p = 1 n / d p ∑ p ∣ i , i ≤ n / d i ∑ j ≤ i σ ( j ) =\sum_{d=1}^{n}\mu(d)d^2\sum_{p=1}^{n/d}p\sum_{p|i,i\le n/d}i\sum_{j\le i}\sigma(j) =d=1nμ(d)d2p=1n/dppi,in/dijiσ(j)
= ∑ d = 1 n μ ( d ) d 2 ∑ i ≤ n / d i ∗ σ ( i ) ∑ j ≤ i σ ( j ) =\sum_{d=1}^{n}\mu(d)d^2\sum_{i\le n/d}i*\sigma(i)\sum_{j\le i}\sigma(j) =d=1nμ(d)d2in/diσ(i)jiσ(j)
已经可以 O ( n ) O(n) O(n) 预处理, O ( n ) O(\sqrt n) O(n ) 查询了,但 T T T 较大
考虑一个 d , i d,i d,i 的贡献,对所有 n ≥ d ∗ i n\ge d*i ndi 都有贡献,于是就可以 O ( n l o g n ) O(nlogn) O(nlogn) 预处理, O ( 1 ) O(1) O(1) 查询
g g g 同理
顺带一提, σ \sigma σ 可以用线性筛,考虑质数次幂的贡献即可
σ ( p ) = p + 1 \sigma(p)=p+1 σ(p)=p+1
σ ( p k ) = ∑ i = 0 k p k \sigma(p^k)=\sum_{i=0}^kp^k σ(pk)=i=0kpk

#include<bits/stdc++.h>
#define cs const
using namespace std;
cs int Mod = 1e9 + 7, N = 1e6 + 5;
int add(int a, int b){ return a + b >= Mod ? a + b - Mod : a + b; } 
int dec(int a, int b){ return a - b < 0 ? a - b + Mod : a - b; }
int mul(int a, int b){ return 1ll * a * b % Mod; }
void Add(int &a, int b){ a = add(a, b); }
int T, n, mu[N], sig[N], Ssig[N];
bool isp[N]; int prim[N], tot;
int Mn[N], vlMn[N], ans[N], f[N], g[N];
void prework(){
	n = 1e6;
	mu[1] = sig[1] = 1;
	for(int i = 2; i <= n; i++){
		if(!isp[i]){
			prim[++tot] = i;
			sig[i] = i+1; mu[i] = Mod-1;
			Mn[i] = 1; vlMn[i] = i+1;
		}
		for(int j = 1; j <= tot; j++){
			if(prim[j] * i > n) break;
			int k = prim[j] * i; isp[k] = true;
			if(i % prim[j] == 0){
				Mn[k] = Mn[i]; mu[k] = 0;
				vlMn[k] = add(mul(vlMn[i], prim[j]), 1);
				sig[k] = mul(vlMn[k], sig[Mn[k]]);
				break;
			}
			Mn[k] = i; vlMn[k] = prim[j]+1;
			mu[k] = mul(mu[i], mu[prim[j]]);
			sig[k] = mul(sig[i], sig[prim[j]]);
		}
	}
	for(int i = 1; i <= n; i++){
		f[i] = mul(mu[i], mul(i,i));
		Ssig[i] = add(Ssig[i-1], sig[i]);
		g[i] = mul(mul(i, sig[i]), dec(mul(2,Ssig[i]),sig[i]));
	}
	for(int i = 1; i <= n; i++)
	for(int j = 1, up=n/i; j <= up; j++)
	Add(ans[i*j], mul(f[i],g[j]));
	for(int i = 1; i <= n; i++) Add(ans[i], ans[i-1]);
} 
int main(){
	prework(); 
	cin >> T; for(int i = 1; i <= T; i++){ 
		scanf("%d", &n); cout << "Case #" << i << ": " << ans[n] << '\n'; 
	} return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FSYo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值