首先(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 }
View Code

相关文章:

  • 2021-10-10
  • 2022-12-23
  • 2021-08-29
  • 2021-07-05
  • 2021-08-23
  • 2021-12-08
  • 2022-02-24
猜你喜欢
  • 2021-07-14
  • 2021-12-21
  • 2021-06-23
  • 2022-12-23
  • 2022-12-23
  • 2021-09-07
  • 2021-09-07
相关资源
相似解决方案