1220 约数之和(杜教筛与莫比乌斯)

2 篇文章 0 订阅
1 篇文章 0 订阅

题目:求 ∑ i = 1 n ∑ j = 1 n σ 1 ( i j ) \sum_{i=1}^n\sum_{j=1}^n\sigma_1(ij) i=1nj=1nσ1(ij)
这题推了一整个下午,留下了不学无术的眼泪orz;

前置公式:
(1) ∑ i = 1 n σ ( i ) = ∑ i = 1 n ∑ j = 1 n [ j ∣ i ] ⋅ j = ∑ i = 1 n i ⋅ ∑ j = 1 n [ i ∣ j ] = ∑ i = 1 n i ⋅ ⌊ n i ⌋ \sum_{i=1}^n\sigma(i)=\sum_{i=1}^n\sum_{j=1}^n[j|i]\cdot j=\sum_{i=1}^ni\cdot \sum_{j=1}^n[i|j]=\sum_{i=1}^ni\cdot⌊\frac{n}{i}⌋ i=1nσ(i)=i=1nj=1n[ji]j=i=1nij=1n[ij]=i=1niin

(2) σ 1 ( i j ) = ∑ x ∣ i ∑ y ∣ j [ g c d ( x , y ) = 1 ] x j y = ∑ x ∣ i ∑ y ∣ i x ⋅ y [ ( i x , y ) = 1 ] \sigma_1(ij)=\sum_{x|i}\sum_{y|j}[gcd(x,y)=1]\frac{xj}{y}=\sum_{x|i}\sum_{y|i}x\cdot y[(\frac{i}{x},y)=1] σ1(ij)=xiyj[gcd(x,y)=1]yxj=xiyixy[(xi,y)=1]

(3) ∑ i = 1 n ∑ j = 1 ⌊ n i ⌋ j = ∑ j = 1 n j ⋅ ⌊ n j ⌋ \sum\limits_{i=1}^n\sum\limits_{j=1}^{⌊\frac{n}{i}⌋}j=\sum\limits_{j=1}^{n}j\cdot⌊\frac{n}{j}⌋ i=1nj=1inj=j=1njjn

(4) ∑ d ∣ n μ ( d ) = [ n = = 1 ] \sum_{d|n}μ(d)=[n==1] dnμd)=[n==1]

(5) ⌊ ⌊ n d ⌋ j ⌋ = ⌊ n d j ⌋ ⌊\frac{⌊\frac{n}{d}⌋}{j}⌋=⌊\frac{n}{dj}⌋ jdn=djn

至于这些公式的证明
第一个已经顺带证明在那了
第二个公式跟 σ 0 ( i j ) = ∑ x ∣ n ∑ y ∣ n [ ( x , y ) = 1 ] \sigma_0(ij)=\sum_{x|n}\sum_{y|n}[(x,y)=1] σ0(ij)=xnyn[(x,y)=1] 的出发差不多
以自己的理解解释一下:简单说明, σ 1 ( n ) = ∏ i ( 1 + p i + p i 2 + p i 3 + ⋯ + p i a i ) \sigma_1(n)=\prod_{i}(1+p_i+p_i^2+p_i^3+\cdots+p_i^{a_i}) σ1(n)=i(1+pi+pi2+pi3++piai)

σ 0 ( n ) \sigma_0(n) σ0(n) 等于上式连乘后产生项的个数,即每一项选一个质数(指数从0到 a i a_i ai )构成一个因数,而对于 σ 0 ( i j ) \sigma_0(ij) σ0(ij) 取每一个 i i i的因子 x x x j j j的每一个因子 y 在 x 与 y y在x与y yxy互质条件下配对(不是指相乘),假设i可分解的连乘部分包括( 1 + p 1 + p 1 2 + p 1 3 1+p_1+p_1^2+p_1^3 1+p1+p12+p13 ), j j j 可出( 1 + p 1 + p 1 2 1+p_1+p_1^2 1+p1+p12 ) 那对于 i j ij ij便可以分出 1 + p 1 + p 1 2 + p 1 3 + p 1 4 + p 1 5 1+p_1+p_1^2+p_1^3+p_1^4+p_1^5 1+p1+p12+p13+p14+p15 那对 i i i在给其因子配质数 p 1 p_1 p1 的方式包括(指数)0,1,2,3,同理j可以0,1,2, i , j i,j i,j可以0,1,2,3,4,5 ,那么问题来了,5等于什么?,等于2+3,那在保证x,y互质的情况下,即保证了其两种选到的因子里包括 p 1 p_1 p1的指数至少有一个一个为零,就相当于选了都为0,和 i i i中的1,2,3和 j j j种的1,2加起来选到 p 1 p_1 p1的方式便跟$ij $ 一样了,所以等式成立
那 么 对 于 σ 1 ( i j ) 来 说 也 是 同 个 道 理 , x j y 相 当 于 你 i 选 了 p 1 指 数 加 上 j 的 p 1 指 数 , 那 这 里 就 可 以 保 证 i j 中 p 1 指 数 每 一 个 都 能 被 选 到 匹 配 成 因 子 , 而 互 质 保 证 了 选 择 上 的 不 重 复 那么对于\sigma_1(ij)来说也是同个道理,\frac{xj}{y}相当于你i选了p_1指数加上j的p_1指数,那这里就可以保证ij中p_1指数每一个都能被选到匹配成因子,而互质保证了选择上的不重复 σ1(ij)yxjip1jp1ijp1
第三个根据贡献值来推
后面两个百度一下有很多

接下来正式推公式

a n s = ∑ i = 1 n ∑ j = 1 n σ 1 ( i j ) ans=\sum\limits_{i=1}^n\sum\limits_{j=1}^n\sigma_1(ij) ans=i=1nj=1nσ1(ij)
= ∑ i = 1 n ∑ j = 1 n ∑ x ∣ i ∑ y ∣ j [ g c d ( x , y ) = 1 ] x j y =\sum\limits_ {i=1}^n\sum\limits_{j=1}^n\sum\limits_{x|i}\sum\limits_{y|j}[gcd(x,y)=1]\frac{xj}{y} =i=1nj=1nxiyj[gcd(x,y)=1]yxj
= ∑ i = 1 n ∑ j = 1 n ∑ x ∣ i ∑ y ∣ j x j y ∑ d ∣ ( x , y ) μ ( d ) =\sum\limits_ {i=1}^n\sum\limits_{j=1}^n\sum\limits_{x|i}\sum\limits_{y|j}\frac{xj}{y}\sum\limits_{d|(x,y)}μ(d) =i=1nj=1nxiyjyxjd(x,y)μd
到这一步就是把前置公式往里套,接下来可以换成枚举d的值,对于每一个 ( x , y ) (x,y) (x,y)d为其的约数,即对于取定一个d, x 和 y x和y xy都是 d d d的倍数,又 x , y x,y x,y分别为 i , j i,j i,j的倍数,所以 i , j i,j i,j只需要枚举d的倍数即可
= ∑ d = 1 n μ ( d ) ∑ d ∣ i n ∑ d ∣ j n ∑ x ∣ i , d ∣ x ∑ y ∣ i , d ∣ y x j y =\sum\limits_{d=1}^n μ(d)\sum\limits_ {d|i}^n\sum\limits_{d|j}^n\sum\limits_{x|i,d|x}\sum\limits_{y|i,d|y}\frac{xj}{y} =d=1nμddindjnxi,dxyi,dyyxj
= ∑ d = 1 n μ ( d ) ∑ d ∣ x n ∑ d ∣ y n ∑ x ∣ i n ∑ y ∣ j n x j y =\sum\limits_{d=1}^nμ(d)\sum\limits_{d|x}^n\sum\limits_{d|y}^n\sum\limits_{x|i}^n\sum\limits_{y|j}^n\frac{xj}{y} =d=1nμddxndynxinyjnyxj
到这一步,令 x = a ⋅ d , y = b ⋅ d , 则 i = k 1 a d , j = k 2 b d x=a\cdot d,y=b\cdot d,则i=k_1ad,j=k_2bd x=ad,y=bd,i=k1ad,j=k2bd代入有
= ∑ d = 1 n μ ( d ) ∑ a = 1 ⌊ n d ⌋ ∑ b = 1 ⌊ n d ⌋ ∑ k 1 = 1 ⌊ n a d ⌋ ∑ k 2 = 1 ⌊ n b d ⌋ k 2 a d =\sum\limits_{d=1}^nμ(d)\sum\limits_{a=1}^{⌊\frac{n}{d}⌋}\sum\limits_{b=1}^{⌊\frac{n}{d}⌋}\sum\limits_{k_1=1}^{⌊\frac{n}{ad}⌋}\sum\limits_{k_2=1}^{⌊\frac{n}{bd}⌋}k_2ad =d=1nμda=1dnb=1dnk1=1adnk2=1bdnk2ad
我们将与 k 2 a d 无 关 的 k 1 放 下 来 k_2ad无关的k_1放下来 k2adk1
= ∑ d = 1 n d μ ( d ) ∑ a = 1 ⌊ n d ⌋ a ⌊ n a d ⌋ ∑ b = 1 ⌊ n d ⌋ ∑ k 2 = 1 ⌊ n b d ⌋ k 2 =\sum\limits_{d=1}^ndμ(d)\sum\limits_{a=1}^{⌊\frac{n}{d}⌋}a⌊\frac{n}{ad}⌋\sum\limits_{b=1}^{⌊\frac{n}{d}⌋}\sum\limits_{k_2=1}^{⌊\frac{n}{bd}⌋}k_2 =d=1ndμda=1dnaadnb=1dnk2=1bdnk2
= ∑ d = 1 n d μ ( d ) ∑ a = 1 ⌊ n d ⌋ a ⋅ ⌊ ⌊ n d ⌋ a ⌋ ∑ b = 1 ⌊ n d ⌋ ∑ k 2 = 1 ⌊ ⌊ n d ⌋ b ⌋ k 2 =\sum\limits_{d=1}^ndμ(d)\sum\limits_{a=1}^{⌊\frac{n}{d}⌋}a\cdot⌊\frac{⌊\frac{n}{d}⌋}{a}⌋\sum\limits_{b=1}^{⌊\frac{n}{d}⌋}\sum\limits_{k_2=1}^{⌊\frac{⌊\frac{n}{d}⌋}{b}⌋}k_2 =d=1ndμda=1dnaadnb=1dnk2=1bdnk2
代入前置公式(3)得
= ∑ d = 1 n d μ ( d ) ∑ a = 1 ⌊ n d ⌋ a ⋅ ⌊ ⌊ n d ⌋ a ⌋ ∑ b = 1 ⌊ n d ⌋ b ⋅ ⌊ ⌊ n d ⌋ b ⌋ =\sum\limits_{d=1}^ndμ(d)\sum\limits_{a=1}^{⌊\frac{n}{d}⌋}a\cdot⌊\frac{⌊\frac{n}{d}⌋}{a}⌋\sum\limits_{b=1}^{⌊\frac{n}{d}⌋}b\cdot⌊\frac{⌊\frac{n}{d}⌋}{b}⌋ =d=1ndμda=1dnaadnb=1dnbbdn
代入前置公式(1)得
= ∑ d = 1 n d μ ( d ) σ 1 2 ( ⌊ n d ⌋ ) =\sum\limits_{d=1}^ndμ(d)\sigma_1^2(⌊\frac{n}{d}⌋) =d=1ndμdσ12(dn)
d ⋅ μ ( d ) 卷 积 后 的 前 缀 和 满 足 M U ( n ) = 1 − ∑ i = 2 n i ⋅ M U ⌊ n i ⌋ d\cdotμ(d)卷积后的前缀和满足MU(n)=1-\sum\limits_{i=2}^ni\cdot MU⌊\frac{n}{i}⌋ dμ(d)MU(n)=1i=2niMUin
接下来杜教筛分块打表即可
代码:

#include <iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#include<map>
#include<vector>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int MX= 1e6;
vector<int>pri;
bool isp[MX];
ll mu[MX];
map<ll, ll>mp;
void init()
{
	isp[0] = isp[1] = false;
	mu[1] = 1;
	for (int i = 2; i < MX; i++) {

		if (isp[i]==0) {
			pri.push_back(i);
			mu[i] = -1;// cout <<i << endl;
		}
		for (int j = 0; j < pri.size() && i * pri[j] < MX; j++) {
			 int cur = i * pri[j];
			isp[cur] =1;
			if (i % pri[j]) {
				mu[cur] = -mu[i];
			}
			else {
				mu[cur] = 0;
				break;
			}
		}
	}
	mu[0] = 0;
	for (int i = 1; i < MX; i++)
	{
		mu[i] = (mu[i - 1] + mu[i] * i)%mod;
	}
}
ll cacl(ll n)
{
	return ((n*(n + 1)) / 2) % mod;
}
ll MU(ll x)
{

	if (x < MX)
	{
		return mu[x];
	}
	if (mp[x])
		return mp[x];
	ll ans = 1, j;
	for (int i = 2; i <= x; i = j + 1)
	{
		j = x / (x / i);
		ans = (ans - 1ll * MU(x / i)*(cacl(j)-cacl( i -1)) %mod+ mod) % mod;

	}
	return mp[x] = ans;
}

ll sigma(ll n)
{
	ll ans = 0;
	ll j;
	for (ll i = 1; i <= n; i++)
	{
		j = n / (n / i);
		ans = (ans + (cacl(j) - cacl(i - 1))*(n/i)) % mod;
		i = j;
	}
		return ans*ans%mod;
}
int main()
{
	init();
	ll n;
	cin >> n;
	ll j;
	ll ans = 0;
	for (int i = 1; i <= n; i++)
	{
		j = n / (n / i);
		ans = (ans + (MU(j) - MU(i - 1))*sigma(n / i)%mod+mod) % mod;
		i = j;
	}
	cout << ans << endl;
	
}在这里插入代码片
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值