hdu1695 GCD(莫比乌斯入门题)

Posted 邀月独斟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu1695 GCD(莫比乌斯入门题)相关的知识,希望对你有一定的参考价值。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695

题意:

 给出n、m、k ,求出1<=x<=n, 1<=y<=m 且gcd(x,y) == k 的(x,y)的对数

解析:

显然就是求 [1,n/k] 与 [1, m/k]有多少数对的最大公约数是1

莫比乌斯入门题

我们设

    为满足的对数

    为满足的对数

 那么,很显然,反演后得到

我们所需要的答案便是  f(1) = i=1µ(i)*(n/i)*(m/i)  ,求解这个式子我们可以分块求和,复杂度为O(√n)。

最后注意由于题目要求,需要将重复的去掉。

代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 
 6 using namespace std;
 7 const int maxn=100010;
 8 
 9 int vis[maxn];
10 int prime[maxn];
11 int cnt;
12 int mu[maxn];
13 int sum[maxn];
14 
15 void init()
16 {
17     memset(vis,0,sizeof(vis));
18     cnt=0;
19     mu[1]=1;
20     for(int i=2;i<maxn;i++)
21     {
22         if(!vis[i])
23         {
24             prime[cnt++]=i;
25             mu[i]=-1;
26         }
27         for(int j=0;j<cnt&&i*prime[j]<maxn;j++)
28         {
29             vis[i*prime[j]]=1;
30             if(i%prime[j])
31                 mu[i*prime[j]]=-mu[i];
32             else
33             {
34                 mu[i*prime[j]]=0;
35                 break;
36             }
37         }
38     }
39     sum[0]=0;
40     for(int i=1;i<maxn;i++)
41         sum[i]=sum[i-1]+mu[i];
42 }
43 
44 int main()
45 {
46     int a,b,c,d,k;
47     init();
48     int T,ca=1;
49     scanf("%d",&T);
50     while(T--)
51     {
52         scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
53         printf("Case %d: ",ca++);
54         if(k==0)
55         {
56             printf("0\\n");
57             continue;
58         }
59         b=b/k;
60         d=d/k;
61         if(b>d)
62             swap(b,d);
63         long long ans1=0;
64         int last;
65         for(int i=1;i<=b;i=last+1)
66         {
67             last=min(b/(b/i),d/(d/i));
68             ans1+=(long long)(sum[last]-sum[i-1])*(b/i)*(d/i);
69         }
70         long long ans2=0;
71         for(int i=1;i<=b;i=last+1)
72         {
73             last=b/(b/i);
74             ans2+=(long long)(sum[last]-sum[i-1])*(b/i)*(b/i);
75         }
76         long long ans=ans1-ans2/2;
77         printf("%lld\\n",ans);
78     }
79     return 0;
80 }
View Code

 

以上是关于hdu1695 GCD(莫比乌斯入门题)的主要内容,如果未能解决你的问题,请参考以下文章

莫比乌斯二连 HDU 5212 Code & HDU 1695 GCD

HDU1695GCD(莫比乌斯反演)

hdu1695 GCD(莫比乌斯反演)

hdu-1695 GCD(莫比乌斯反演)

(HDU 1695)GCD(容斥+莫比乌斯反演)

莫比乌斯反演HDU1695_GCD