首先(1,b)(1,d)->(1,b/k)(1,d/k)转化为互质对数
设F(k)为gcd(x,y)为k的倍数的对数->F(k)=(b/k)*(d/k)
f[1]=mu[1]*F[1]+mu[2]*F[2]+...mu[m]*F[m]
再减去重复计算的,变了F[i]再做一遍==
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 #define maxn 100005 6 #define LL long long 7 LL vis[maxn],prime[maxn],mu[maxn]; 8 void mobius() 9 { 10 LL cnt=0,i,j; 11 memset(vis,0,sizeof(vis)); 12 mu[1]=1; 13 for (i=2;i<=maxn;i++){ 14 if (vis[i]==0){ 15 prime[++cnt]=i; 16 mu[i]=-1; 17 } 18 for (j=1;j<=cnt;j++){ 19 if (i*prime[j]>maxn) break; 20 vis[i*prime[j]]=1; 21 if (i%prime[j]==0){mu[i*prime[j]]=0; break;} 22 else mu[i*prime[j]]=-mu[i]; 23 } 24 } 25 } 26 int main() 27 { 28 LL T,t,a,b,c,d,k,a1,a2,i; 29 mobius(); 30 scanf("%I64d",&T); 31 for (t=1;t<=T;t++){ 32 scanf("%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&d,&k); 33 printf("Case %I64d: ",t); 34 if (k==0) {printf("0\n"); continue; } 35 b/=k; d/=k; 36 if (b>d) swap(b,d); 37 a1=a2=0; 38 for (i=1;i<=b;i++){ 39 a1+=mu[i]*(b/i)*(d/i); 40 a2+=mu[i]*(b/i)*(b/i); 41 } 42 printf("%I64d\n",a1-a2/2); 43 } 44 return 0; 45 }