const int N = 5e5 + 5;
int mob[N + 1], p[N + 1], num[N + 1],sum[N+1][20],cnt;
bool vis[N + 1];
void x_x()
{
mob[1] = 1;
f(i, 2, N)
{
if (!vis[i])
{
p[++cnt] = i;
num[i] = 1;
mob[i] = -1;
}
for (int j = 1;p[j] <= N / i;j++)
{
vis[p[j] * i] = true;
num[p[j] * i] = num[i] + 1;
if (i%p[j] == 0)
{
mob[i*p[j]] = 0;
break;
}
mob[i*p[j]] = -mob[i];
}
}
}
void work()
{
x_x();
f(i, 1, N)
for (int j = i;j <= N;j += i)
sum[j][num[i]] += mob[j / i];
//f(i, 1, 10)debug(sum[i][1]);
//[每一个数,对每个次数的贡献]
f(i, 1, N)
f(j, 1, 18)
sum[i][j] += sum[i][j - 1];
//计算了第二维的前缀,sum[每一个数,对前缀次数的贡献]
f(i, 0, 18)
f(j, 1, N)
sum[j][i] += sum[j-1][i];
//计算了第一维的前缀,sum[前缀所有数,对前缀次数的贡献]
}
int main()
{
//freopen("in.txt", "r", stdin);
work();
int n, m, k;
int t;cin >> t;
while (t--)
{
scanf("%d%d%d", &n, &m, &k);
ll ans = 0;
k = min(k, 18);
for(int l=1;l<=min(n,m);)
{
int r = min(n / (n / l), m / (m / l));
ans += (ll)(n / l)*(m / l)*(sum[r][k] - sum[l - 1][k]);
l = r + 1;
}
cout << ans << endl;
}
return 0;
}
Mophues HDU - 4746(莫比乌斯反演,整除分块)
最新推荐文章于 2021-05-30 16:44:55 发布