Problem Description
2 10 10 0 10 10 1
63 93
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
int const MAX = 5e5 + 5;
int n, m, p, pnum;
int mob[MAX], pr[MAX], sum[MAX][20];
int num[MAX];
bool prime[MAX];
void Mobius()
{
pnum = 0;
memset(prime, true, sizeof(prime));
mob[1] = 1;
for(int i = 2; i < MAX; i++)
{
if(prime[i])
{
pr[pnum ++] = i;
num[i] = 1;
mob[i] = -1;
}
for(int j = 0; j < pnum && i * pr[j] < MAX; j++)
{
num[i * pr[j]] = num[i] + 1;
prime[i * pr[j]] = false;
if(i % pr[j] == 0)
{
mob[i * pr[j]] = 0;
break;
}
mob[i * pr[j]] = -mob[i];
}
}
}
void Init()
{
Mobius();
for(int i = 1; i < MAX; i++)
for(int j = i; j < MAX; j += i)
sum[j][num[i]] += mob[j / i];
for(int i = 1; i < MAX; i++)
for(int j = 1; j < 19; j++)
sum[i][j] += sum[i][j - 1];
for(int i = 1; i < MAX; i++)
for(int j = 0; j < 19; j++)
sum[i][j] += sum[i - 1][j];
}
ll cal(int l, int r)
{
ll ans = 0;
if(l > r)
swap(l, r);
for(int i = 1, last = 0; i <= l; i = last + 1)
{
last = min(l / (l / i), r / (r / i));
ans += (ll) (l / i) * (r / i) * (sum[last][p] - sum[i - 1][p]);
}
return ans;
}
int main()
{
Init();
int T;
scanf("%d", &T);
while(T --)
{
scanf("%d %d %d", &n, &m, &p);
printf("%lld\n", p > 18 ? (ll) n * m : cal(n, m));
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/tc_to_top/article/details/47829907