题意:求(sumlimits_{i=1}^n sumlimits_{j=1}^m [gcd(i,j)=k]),多组询问
简单套路一下
[sum_{d=1}^n mu(d) frac{n}{kd} frac{m}{kd}
]
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=5e4+5;
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
return x*f;
}
int n, m, k;
int notp[N], p[N], mu[N];
void sieve(int n) {
mu[1] = 1;
for(int i=2; i<=n; i++) {
if(!notp[i]) p[++p[0]] = i, mu[i] = -1;
for(int j=1; j<=p[0] && i*p[j]<=n; j++) {
notp[i*p[j]] = 1;
if(i%p[j] == 0) {mu[i*p[j]] = 0; break;}
mu[i*p[j]] = -mu[i];
}
}
for(int i=1; i<=n; i++) mu[i] += mu[i-1];
}
ll cal(int n, int m, int k) {
n /= k; m /= k;
if(n > m) swap(n, m);
ll ans=0; int r;
for(int i=1; i<=n; i=r+1) {
r = min(n/(n/i), m/(m/i));
ans += (ll)(mu[r] - mu[i-1]) * (n/i) * (m/i);
}
return ans;
}
int main() {
//freopen("in","r",stdin);
sieve(N-1);
int T=read();
while(T--) {
n=read(); m=read(); k=read();
printf("%lld
", cal(n, m, k));
}
}