∑na=1∑mb=1[gcd(a,b)=D]−>
∑Na=1∑Mb=1[gcd(a,b)=1] (N=⌊n/D⌋) (M=⌊m/D⌋)−>
∑Na=1∑Mb=1∑d|gcd(a,b)μ(d)−>
∑dμ(d)∑⌊n/d⌋a=1∑⌊m/d⌋b=1
线性筛个
μ
<script type="math/tex" id="MathJax-Element-425">μ</script>,维护一下前缀和就好了
为什么我用longlongWA,用int就A了,我用了lld啊…….
整天把true打成false也是没救了
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<vector>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = 100001;
int p[maxn],pri;
bool v[maxn];
int miu[maxn],sum[maxn];
int n,m;
int main()
{
miu[1]=1; sum[1]=1;
for(int i=2;i<maxn;i++)
{
if(!v[i])
{
p[++pri]=i;
miu[i]=-1;
}
for(int j=1;j<=pri&&p[j]*i<maxn;j++)
{
int k=p[j]*i;
v[k]=true;
if(i%p[j]==0)
{
miu[k]=0;
break;
}
miu[k]=-miu[i];
}
sum[i]=sum[i-1]+miu[i];
}
int t;scanf("%d",&t);
while(t--)
{
int x; scanf("%d%d%d",&n,&m,&x);
n/=x; m/=x;
int l=1,r=min(n,m);
int ret=0;
while(l<=r)
{
int nex=min(n/(n/l),m/(m/l));
int s=(n/l)*(m/l);
ret+=(sum[nex]-sum[l-1])*s;
l=nex+1;
}
printf("%d\n",ret);
}
return 0;
}