HDU 6428 Problem C. Calculate(数论+莫比乌斯反演)

本文介绍了一种基于数论的方法来解决特定的三重求和问题,并通过线性筛法预处理关键函数,实现了高效的查询算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

∑i=1A∑j=1B∑k=1Cφ(gcd(i,j2,k3))(mod 230)\sum\limits_{i=1}^{A}\sum\limits_{j=1}^B\sum\limits_{k=1}^C\varphi(gcd(i,j^2,k^3))(mod\ 2^{30})i=1Aj=1Bk=1Cφ(gcd(i,j2,k3))(mod 230)

Input

第一行一整数TTT表示用例组数,每组用例输入三个整数A,B,C(1≤T≤10,1≤A,B,C≤107)A,B,C(1\le T\le 10,1\le A,B,C\le 10^7)A,B,C(1T10,1A,B,C107)

Output

输出答案

Sample Input

4
96 93 95
970 906 893
92460 95043 54245
9760979 8053227 7156842

Sample Output

1114536
28070648
388873924
623507672

Solution

首先有
ans=∑i=1A∑d∣iφ(d)⋅s(i,B,C,d) \begin{array}{lcl} ans=\sum\limits_{i=1}^A\sum\limits_{d|i}\varphi(d)\cdot s(i,B,C,d) \end{array} ans=i=1Adiφ(d)s(i,B,C,d)
其中s(i,B,C,d)s(i,B,C,d)s(i,B,C,d)表示满足gcd(i,j2,k3)=d,1≤j≤B,1≤k≤Cgcd(i,j^2,k^3)=d,1\le j\le B,1\le k\le Cgcd(i,j2,k3)=d,1jB,1kC的二元组(j,k)(j,k)(j,k)的个数

S(i,B,C,d)S(i,B,C,d)S(i,B,C,d)表示满足d∣gcd(i,j2,k3),1≤j≤B,1≤k≤Cd|gcd(i,j^2,k^3),1\le j\le B,1\le k\le Cdgcd(i,j2,k3),1jB,1kC的二元组(j,k)(j,k)(j,k)的个数,那么有
S(i,B,C,d)=∑d∣n∣is(i,B,C,k) S(i,B,C,d)=\sum\limits_{d|n|i}s(i,B,C,k) S(i,B,C,d)=dnis(i,B,C,k)
考虑求S(i,B,C,d)S(i,B,C,d)S(i,B,C,d),也即分别求出求d∣j2,1≤j≤Bd|j^2,1\le j\le Bdj2,1jB的个数和d∣k3,1≤k≤Cd|k^3,1\le k\le Cdk3,1kC的个数

ddd质因子分解有d=p1a1...pmamd=p_1^{a_1}...p_m^{a_m}d=p1a1...pmam,记f(d)=p1⌊a1+12⌋...pm⌊am+12⌋,g(d)=p1⌊a1+23⌋...pm⌊am+23⌋f(d)=p_1^{\lfloor\frac{a_1+1}{2}\rfloor}...p_m^{\lfloor\frac{a_m+1}{2}\rfloor},g(d)=p_1^{\lfloor\frac{a_1+2}{3}\rfloor}...p_m^{\lfloor\frac{a_m+2}{3}\rfloor}f(d)=p12a1+1...pm2am+1,g(d)=p13a1+2...pm3am+2,显然f,gf,gf,g均为积性函数,且d∣j2d|j^2dj2等价于f(d)∣jf(d)|jf(d)jd∣k3d|k^3dk3等价于g(d)∣kg(d)|kg(d)k,故线性筛求出f,gf,gf,g后即可O(1)O(1)O(1)得到S(i,B,C,d)=⌊Bf(d)⌋⋅⌊Cg(d⌋S(i,B,C,d)=\lfloor\frac{B}{f(d)}\rfloor\cdot \lfloor\frac{C}{g(d}\rfloorS(i,B,C,d)=f(d)Bg(dC

之后由莫比乌斯反演有
s(i,B,C,d)=∑d∣n∣iμ(nd)⋅S(i,B,C,n) s(i,B,C,d)=\sum\limits_{d|n|i}\mu(\frac{n}{d})\cdot S(i,B,C,n) s(i,B,C,d)=dniμ(dn)S(i,B,C,n)
故有
ans=∑i=1A∑d∣iφ(d)∑d∣nμ(nd)⋅S(i,B,C,n)=∑i=1A∑d∣iφ(d)∑d∣n∣iμ(nd)⋅⌊Bf(n)⌋⋅⌊Cg(n⌋=∑n=1A⌊An⌋⋅⌊Bf(n)⌋⋅⌊Cg(n⌋∑d∣nφ(d)⋅μ(nd) \begin{array}{lcl} ans&=&\sum\limits_{i=1}^A\sum\limits_{d|i}\varphi(d)\sum\limits_{d|n}\mu(\frac{n}{d})\cdot S(i,B,C,n)\\ &=&\sum\limits_{i=1}^A\sum\limits_{d|i}\varphi(d)\sum\limits_{d|n|i}\mu(\frac{n}{d})\cdot \lfloor\frac{B}{f(n)}\rfloor\cdot \lfloor\frac{C}{g(n}\rfloor \\ &=&\sum\limits_{n=1}^A\lfloor\frac{A}{n}\rfloor\cdot \lfloor\frac{B}{f(n)}\rfloor\cdot \lfloor\frac{C}{g(n}\rfloor\sum\limits_{d|n}\varphi(d)\cdot \mu(\frac{n}{d})\\ \end{array} ans===i=1Adiφ(d)dnμ(dn)S(i,B,C,n)i=1Adiφ(d)dniμ(dn)f(n)Bg(nCn=1AnAf(n)Bg(nCdnφ(d)μ(dn)
h(n)=∑d∣nφ(d)⋅μ(nd)h(n)=\sum\limits_{d|n}\varphi(d)\cdot \mu(\frac{n}{d})h(n)=dnφ(d)μ(dn),由于φ,μ\varphi,\muφ,μ都是积性函数,那么它们的狄利克雷卷积也是积性函数,故同样可以线性筛求出hhh,注意到h(p)=φ(1)μ(p)+φ(p)μ(1)=p−2h(p)=\varphi(1)\mu(p)+\varphi(p)\mu(1)=p-2h(p)=φ(1)μ(p)+φ(p)μ(1)=p2,而由φ(pc)=pc−pc−1\varphi(p^c)=p^c-p^{c-1}φ(pc)=pcpc1以及μ(pc)=0,c≥2\mu(p^c)=0,c\ge 2μ(pc)=0,c2可得
h(pc)=∑i=0cφ(pi)μ(pc−i)=φ(pc)μ(1)+φ(pc−1)μ(p)=pc−2pc−1+pc−2 h(p^c)=\sum\limits_{i=0}^c\varphi(p^i)\mu(p^{c-i})=\varphi(p^c)\mu(1)+\varphi(p^{c-1})\mu(p)=p^c-2p^{c-1}+p^{c-2} h(pc)=i=0cφ(pi)μ(pci)=φ(pc)μ(1)+φ(pc1)μ(p)=pc2pc1+pc2
用线性筛O(n)O(n)O(n)预处理出φ,μ,f,g,h\varphi,\mu,f,g,hφ,μ,f,g,h即可O(A)O(A)O(A)查询

Code

#include<cstdio>
using namespace std;
typedef long long ll;
#define maxn 10000005
#define mod (1<<30)
int mul(int x,int y)
{
	ll z=1ll*x*y;
	return z-z/mod*mod;
}
int add(int x,int y)
{
	x+=y;
	if(x>=mod)x-=mod;
	return x;
}
int prime[maxn],res,euler[maxn],f[maxn],g[maxn],h[maxn],mu[maxn],mark[maxn];
void get_euler(int n=1e7)
{
    euler[1]=mu[1]=f[1]=g[1]=h[1]=mark[1]=1;
    res=0;
    for(int i=2;i<=n;i++)
    {
        if(!euler[i])
		{
			euler[i]=i-1,prime[res++]=i,mu[i]=-1,f[i]=i,g[i]=i,h[i]=i-2,mark[i]=i;
		}
        for(int j=0;j<res&&prime[j]*i<=n;j++)
        {
            if(i%prime[j]) 
			{
				euler[prime[j]*i]=euler[i]*(prime[j]-1);
				mu[i*prime[j]]=-mu[i];
				f[i*prime[j]]=f[i]*prime[j];
				g[i*prime[j]]=g[i]*prime[j];
				mark[i*prime[j]]=prime[j];
				h[i*prime[j]]=h[i]*h[prime[j]];
			}
            else
            {
                euler[prime[j]*i]=euler[i]*prime[j];
                mu[i*prime[j]]=0;
                f[i*prime[j]]=f[i/prime[j]]*prime[j];
                if((i/prime[j])%prime[j]==0)g[i*prime[j]]=g[i/prime[j]/prime[j]]*prime[j];
                else g[i*prime[j]]=g[i];
                mark[i*prime[j]]=mark[i]*prime[j];
                if(i*prime[j]==mark[i*prime[j]])
                	h[i*prime[j]]=add(add(i*prime[j],mod-mul(2,i)),i/prime[j]);
                else
                	h[i*prime[j]]=h[i/mark[i]]*h[mark[i*prime[j]]];
                break;
            }
        }
    }
}
int main()
{
	get_euler();
	int T,A,B,C;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d%d",&A,&B,&C);
		int ans=0;
		for(int d=1;d<=A;d++)ans=add(ans,mul(mul(h[d],A/d),mul(B/f[d],C/g[d])));
		printf("%d\n",ans);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值