洛谷 4450

题目链接: P4450 双亲数

题目大意: 我们以 d = g c d ( a , b ) d=gcd(a,b) d=gcd(a,b) 表示 a a a b b b 的最大公约数,现已知 a ≤ A , b ≤ B a\leq A,b\leq B aA,bB 求满足 d = g c d ( a , b ) d=gcd(a,b) d=gcd(a,b) a a a b b b 有多少对。

题目分析: 我们设题目中要求的答案为 f ( x ) f(x) f(x)
f ( x ) = ∑ i = 1 A ∑ j = 1 B [ g c d ( i , j ) = = d ] f(x)=\sum_{i=1}^A\sum_{j=1}^B[gcd(i,j)==d] f(x)=i=1Aj=1B[gcd(i,j)==d]
另外设 g ( x ) = ∑ x ∣ d f ( d ) g(x)=\sum_{x|d}f(d) g(x)=xdf(d) A A A B B B 同时除以 d d d A ′ A' A B ′ B' B ,则 f ( x ) f(x) f(x) 可化为 f ( x ) = ∑ i = 1 A ′ ∑ j = 1 B ′ [ g c d ( i , j ) = = 1 ] f(x)=\sum_{i=1}^{A'}\sum_{j=1}^{B'}[gcd(i,j)==1] f(x)=i=1Aj=1B[gcd(i,j)==1] g ( x ) g(x) g(x) 反演可以得出 f ( x ) = ∑ x ∣ d μ ( d x ) g ( d ) f(x)=\sum_{x|d}\mu(\frac{d}{x})g(d) f(x)=xdμ(xd)g(d) x = 1 x=1 x=1 f ( 1 ) = ∑ 1 ∣ d μ ( d 1 ) g ( d ) f(1)=\sum_{1|d}\mu(\frac{d}{1})g(d) f(1)=1dμ(1d)g(d) f ( 1 ) = ∑ i = 1 n μ ( i ) g ( i ) f(1)=\sum_{i=1}^{n}\mu(i)g(i) f(1)=i=1nμ(i)g(i)而对于 g ( x ) g(x) g(x) f ( x ) f(x) f(x) 带入可得 g ( x ) = ∑ x ∣ d ∑ i = 1 A ∑ j = 1 B [ g c d ( i , j ) = = d ] g(x)=\sum_{x|d}\sum_{i=1}^{A}\sum_{j=1}^{B}[gcd(i,j)==d] g(x)=xdi=1Aj=1B[gcd(i,j)==d] g ( x ) = ∑ i = 1 A ∑ j = 1 B [ x ∣ g c d ( i , j ) ] g(x)=\sum_{i=1}^{A}\sum_{j=1}^{B}[x|gcd(i,j)] g(x)=i=1Aj=1B[xgcd(i,j)]进一步变形 g ( x ) = ∑ i = 1 ⌊ A x ⌋ ∑ j = 1 ⌊ B x ⌋ [ 1 ∣ g c d ( i , j ) ] g(x)=\sum_{i=1}^{\lfloor \frac{A}{x} \rfloor}\sum_{j=1}^{\lfloor \frac{B}{x} \rfloor}[1|gcd(i,j)] g(x)=i=1xAj=1xB[1gcd(i,j)]
g ( x ) = ⌊ A x ⌋ ⌊ B x ⌋ g(x)=\lfloor \frac{A}{x} \rfloor\lfloor \frac{B}{x} \rfloor g(x)=xAxB
带回到 f ( x ) f(x) f(x) f ( 1 ) = ∑ i = 1 A ⌊ A x ⌋ ⌊ B x ⌋ μ ( i ) f(1)=\sum_{i=1}^A\lfloor \frac{A}{x} \rfloor\lfloor \frac{B}{x} \rfloor\mu(i) f(1)=i=1AxAxBμ(i)最后只需要线性筛出 μ ( i ) \mu(i) μ(i)即可。下面是完整代码:
题目代码:

#include<stdio.h> 
#include<algorithm>
#include<string.h>
#define mxn 1100000
#define LL long long
#define min(a,b)(a<b?a:b)
#define swap(a,b)(a+=b,b=a-b,a=a-b)
using namespace std;
LL mu[mxn],prime[mxn],used[mxn],cnt,sum[mxn];
inline void get_mu()
{
	LL n=mxn;
    mu[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(!used[i]){
			prime[++cnt]=i;
			mu[i]=-1;
		}
        for(int j=1;j<=cnt&&i*prime[j]<=n;++j)
        {
            used[i*prime[j]]=1;
            if(i%prime[j]==0)break;
            else mu[i*prime[j]]=-mu[i];
        }
    }
    for(int i=1;i<=n;i++)
		sum[i]=sum[i-1]+mu[i];
}
int main()
{
	LL A,B,d;
	LL ans;
	get_mu();
	scanf("%lld %lld %lld",&A,&B,&d);
	A/=d;B/=d;
	if(A>B)swap(A,B);
	for(LL l=1,r;l<=A;l=r+1)
    {
        r=min(A/(A/l),B/(B/l));
        ans+=(A/l)*(B/l)*(sum[r]-sum[l-1]);
    }
	printf("%lld\n",ans);
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值