As we know, any positive integer C ( C >= 2 ) can be written as the multiply of some prime numbers:
C = p1×p2× p3× ... × pk
which p1, p2 ... pk are all prime numbers.For example, if C = 24, then:
24 = 2 × 2 × 2 × 3
here, p1 = p2 = p3 = 2, p4 = 3, k = 4
Given two integers P and C. if k<=P( k is the number of C's prime factors), we call C a lucky number of P.
Now, XXX needs to count the number of pairs (a, b), which 1<=a<=n , 1<=b<=m, and gcd(a,b) is a lucky number of a given P ( "gcd" means "greatest common divisor").
Please note that we define 1 as lucky number of any non-negative integers because 1 has no prime factor.
C = p1×p2× p3× ... × pk
which p1, p2 ... pk are all prime numbers.For example, if C = 24, then:
24 = 2 × 2 × 2 × 3
here, p1 = p2 = p3 = 2, p4 = 3, k = 4
Given two integers P and C. if k<=P( k is the number of C's prime factors), we call C a lucky number of P.
Now, XXX needs to count the number of pairs (a, b), which 1<=a<=n , 1<=b<=m, and gcd(a,b) is a lucky number of a given P ( "gcd" means "greatest common divisor").
Please note that we define 1 as lucky number of any non-negative integers because 1 has no prime factor.
Then Q lines follow, each line is a test case and each test case contains three non-negative numbers: n, m and P (n, m, P <= 5×10 5. Q <=5000).
Output
Sample Input
2 10 10 0 10 10 1
63
93
还是老样子,设 f(d) 为 gcd( a, b )=d 的数目,则F( d ) 为 gcd (a , b) 是 d 的倍数的数目,则F(d)就是(n/d)*(m/d)
然后有:(设 miu[ ] 是莫比乌斯函数)
f(1)=miu(1)*F(1)+miu(2)*F(2)+.........+miu(p1*p2*......*pi)*F(p1*p2*.......*pi)
f(2)=miu(1)*F(1*2)+miu(2)*F(2*2)+..........+miu(p1*p2*.....*pj)*F(p1*p2*.......*pj*2)
………………
f(d)=miu(1)*F(1*d)+miu(2)*F(2*d)+..........+miu(p1*p2*.....*pk)*F(p1*p2*.......*pk*d)
然后把 f(i) 中的质因子个数小于等于 p 的 i 对应的 f(i)加起来就得到 ans=f(1)+f(2)+.....+f(i)+........ = a(1)*F(1)+a(2)*F(2)+.......+a(i)*F(i)+.......
其中a(i)为 i 相同的F(i)对应的各种 miu(i / j)的和。。。。。emmm…… 也就是说,对于一个 j ,筛出他的倍数 i ,则这个 j 对 F(i) 的贡献为 a( i )+=miu(i / j)。。。
然后莫比乌斯函数求和啊分段把 F(i) 加起来啊就完了
(我好没用实在讲不清楚。。。。。。。。)
当然,同时还要注意 gcd 是不是 lucky number ,也就是限制其质因子个数小于等于 p
这个时候我们可以开一个二维数组 a[ i ][ j ] 表示 i 的倍数中质因子个数至多为 j,用这个数组来存对应的莫比乌斯函数的和
以下 K[ i ] 表示 i 的质因子有多少个,这个题他时间卡的紧(反正我是这么觉得),所以 K 数组不要用传统的那种一个一个遍历素数表的方法打表,会T的
可以跟着素数表直接打出来,这个比较快。
还有,以下 F[ i ][ j ] 即上述的 a[ i ][ j ]
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
typedef long long LL;
const LL MOD=1e9+7;
#define fi first
#define se second
const int MAXN=1000000+23;
LL prime[MAXN],total,miu[MAXN];
bool isprime[MAXN];
LL F[MAXN][23],K[MAXN];
void make()
{
int m=MAXN-3;
memset(isprime,true,sizeof(isprime));
memset(K,0,sizeof(K));
total=0;
isprime[0]=isprime[1]=false;
miu[1]=1;
for(int i=2;i<=m;i++)
{
if(isprime[i]){prime[++total]=i;miu[i]=-1;K[i]=1;}
for(int j=1;j<=total&&prime[j]*i<=m;j++)
{
K[i*prime[j]]=K[i]+1;
isprime[i*prime[j]]=false;
if(i%prime[j])
{
miu[i*prime[j]]=-miu[i];
}
else
{
miu[i*prime[j]]=0;
break;
}
}
}
miu[0]=0;
// for(int i=1;i<=m;i++)miu[i]+=miu[i-1];
}
LL n,m,p;
void Init()
{
LL m=5e5+230,_max=0;
for(LL i=1;i<=m;i++)
{
_max=max(_max,K[i]);
for(int j=1;j*i<=m;j++)
{
F[j*i][K[i]]+=miu[j];
}
}
for(int j=1;j<=m;j++)
{
for(int i=1;i<=_max;i++)
{
F[j][i]+=F[j][i-1];
}
}
for(int i=0;i<=_max;i++)
{
for(int j=2;j<=m;j++)
{
F[j][i]+=F[j-1][i];
}
}
}
int main()
{
make();
Init();
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld%lld",&n,&m,&p);
if(p>18)
{
printf("%lld\n",n*m);
continue;
}
if(n>m)swap(n,m);
LL ans=0;
for(LL i=1,last=0;i<=n;i=last+1)
{
last=min(n/(n/i),m/(m/i));
ans+=(F[last][p]-F[i-1][p])*((n/i)*(m/i));
}
printf("%lld\n",ans);
}
return 0;
}
emmmm............我才刚开始莫比乌斯专题,对每个题目的理解度不高,比如这个题目写的博客就和大佬们差距灰常大,所以请各位多多指正在下文意不清或者是有错误的地方
。。。。。。。(怀疑人生中)