题意:定义x,p:假如x的所有质因数的个数小于等于p,则称x is a lucky number of P.然后问你1<=x<=n
1<=y<=m中,有多少对(x,y)满足gcd(x,y)is a lucky number of P.题意:定义x,p:假如x的所有质因数的个数小于等于p,则称x
题解:这道题和之前做的gcd很像,我们可以定义一个函数F(x)表示x有多少个质因数,假设我们当前求gcd(x,y)=d,可以等价于求gcd(x,y)=1 1<=x<=n/d && 1<=y<=m/d...这在之前的题目中已经说明过了,我们仍然可以仿照之前的做法,令f(d)为gcd(x,y)=d的对数,g(d)为gcd(x,y)=d的倍数的个数。显而易见,g(d)可以无脑算出,答案是g(d)=[n/d][m/d]([]为向下取整),然后我们可以利用莫比乌斯反演定理,在O(n)的时间内求出每个值的贡献,然而对于这道题来说是超时的,因此,我们仍然考虑分块,这道题并不想之前呢样简单的求一波前缀和就可以的。
因为涉及到素因数的个数,故要开一个二维的前缀和dp[d][p]:表示质因数个数<=p时对g(d)的贡献系数。
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#include<math.h>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<functional>
using namespace std;
typedef long long ll;
#define inf 1000000000
#define mod 1000000007
#define maxn 560050
#define lowbit(x) (x&-x)
#define eps 1e-9
ll a[maxn] = { 1,1 }, b[maxn], mu[maxn], cnt, num[maxn], dp[maxn][20];
void init()
{
ll i, j;mu[1] = 1;
for (i = 2;i<maxn;i++)
{
if (a[i] == 0)
b[++cnt] = i, mu[i] = -1, num[i] = 1;
for (j = 1;j <= cnt && i*b[j] <= maxn;j++)
{
a[b[j] * i] = 1;
num[b[j] * i] = num[i] + 1;
if (i%b[j] == 0)
{
mu[b[j] * i] = 0;
break;
}
else
mu[b[j] * i] = -mu[i];
}
}
for (i = 1;i <= maxn;i++)
for (j = i;j <= maxn;j += i)
dp[j][num[i]] += mu[j / i];
for (i = 0;i <= maxn;i++)
for (j = 1;j <= 19;j++)
dp[i][j] += dp[i][j - 1];
for (i = 1;i <= maxn;i++)
for (j = 0;j <= 19;j++)
dp[i][j] += dp[i - 1][j];
}
int main(void)
{
init();
ll T, i, x, y, k, p, last;
scanf("%lld", &T);
while (T--)
{
ll sum = 0;
scanf("%lld%lld%lld", &x, &y, &p);
if (x > y) swap(x, y);p = min(p, 18ll);
for (i = 1, last = 0;i <= x;i = last + 1)
{
last = min(x / (x / i), y / (y / i));
sum += (ll)(dp[last][p] - dp[i-1][p])*(x / i)*(y / i);
}
printf("%lld\n", sum);
}
return 0;
}