Problem Description
Given A, B, C, Calculate
Where φ(n) denotes the number of positive integers ≤ n that are relatively prime to n.
Input
The first line of the input contains an integer T , denoting the number of test cases. In each test case, there are three integers A, B, C in one line, as described above.
1 ≤ T ≤ 10, 0 < A, B, C ≤ 10^7
Output
For each test case, output one line contains a single integer, denoting the answer modulo 2^30.
Sample Input
4
96 93 95
970 906 893
92460 95043 54245
9760979 8053227 7156842
Sample Output
1114536
28070648
388873924
623507672
为方便起见下文
(a,b)
(
a
,
b
)
均指代
gcd(a,b)
g
c
d
(
a
,
b
)
题解给的东西跳过太多步骤了,我觉正常思路应该是这样的:
易知有:
所以有:
那么到这里,我们去枚举 t=l∗d t = l ∗ d ,显然我们可以发现t是同样满足 t|i,t|j2,t|k3 t | i , t | j 2 , t | k 3 .那么里面的l和d就是一个狄利克雷卷积的形式了
得:
这里才到题解的第一步……..
后面就是反演的套路啊,把里面的东西拿到外面来:
至于后面这个东西,也的确是厉害,但是只要用唯一分解定理简单分析一下,其实就是可以了
A的个数显然是
At
A
t
那第二个呢?实际上j平方代表了本来我的因子不够,但是平方了以后就足够整除t了,所以答案一定变大的,本质原因就是对于
k
k
次:
显然k等于1时, f1(x)=x f 1 ( x ) = x ,那么B就是 Bf2(t) B f 2 ( t ) ,C的贡献就是 Cf3(t) C f 3 ( t )
狄利克雷卷积是积性, fk f k 显然也是积性均可以线性筛。
就可以做了。。。。。。
具体实现,需要记录一下每个数最小质因子的幂次,来得到 fk f k
这题如果不用unsigned int就会超时啊。。。
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define ull unsigned long long
#define ll long long
#define ul unsigned int
#define maxn 10000005
using namespace std;
ul mod=1<<30;
bool isP[maxn];
int prime[maxn],cnt=0;
int g[maxn];
int e[maxn];//数中最小质数的幂次大小
int p[maxn];
int f2[maxn],f3[maxn];
void init()
{
g[1]=f2[1]=f3[1]=1;
for(int i=2;i<maxn;i++)
{
if(!isP[i])
{
prime[cnt++]=i;
g[i]=i-2;
e[i]=1;
p[i]=f2[i]=f3[i]=i;
}
for(int j=0;j<cnt&&(ll)i*prime[j]<maxn;j++)
{
int _p=prime[j];
int now=i*_p;
isP[now]=true;
if(i%_p)
{
e[now]=1;
p[now]=_p;
f2[now]=f2[i]*_p;
f3[now]=f3[i]*_p;
g[now]=g[i]*(_p-2);
}
else
{
e[now]=e[i]+1;
p[now]=p[i]*_p;
f2[now]=f2[i]*(e[i]%2?1:_p);
f3[now]=f3[i]*(e[i]%3?1:_p);
g[now]=(p[now]-p[now]/_p*2+p[now]/(_p*_p))*g[now/p[now]];
break;
}
}
}
}
int A,B,C;
int main()
{
init();
int t;
cin>>t;
while(t--)
{
cin>>A>>B>>C;
ul ans=0;
for(int i=1;i<=A;i++)
ans+=g[i]*(A/i)*(B/f2[i])*(C/f3[i]);
cout<<(ans&(mod-1))<<endl;
}
return 0;
}