洛谷2257 YY的GCD

傳送機

神犇YY虐完數論後給傻×kAc出了一題

給定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)爲質數的(x, y)有多少對

kAc這種傻×必然不會了,於是向你來請教……

多組輸入

$Ans = \sum\limits_{i = 1}^{n}\sum\limits_{j = 1}^{m}[Gcd(i , j) = prime]$ 
記$f(x) = \sum\limits_{i = 1}^{n}\sum\limits_{j = 1}^{m}[Gcd(i , j) = x]$ 
記$F(x) = \sum\limits_{x|n}f(n)$ 
腦補一下 , 可看出$F(x) = \lfloor{\dfrac{n}{x}}\rfloor\lfloor{\dfrac{m}{x}}\rfloor$ 
由於莫比烏斯反演可以得到 
$f(x) = \sum\limits_{x|d}{\mu(\dfrac{d}{x})\times F(d)}$ 
準備工作做完了 , 開始推式子 
$Ans = \sum\limits_{p\ \in\ Prime}\ \sum\limits_{i = 1}^{n}\sum\limits_{j = 1}^{m}[Gcd(i , j) = p]$ 
$=\sum\limits_{p\ \in\ Prime}\ f(p)$ 
$=\sum\limits_{p\ \in\ Prime}\ \sum\limits_{p|d}{\mu(\dfrac{d}{p})\times F(d)}$ 
換枚舉$\dfrac{d}{p}$ 
$=\sum\limits_{p\ \in\ Prime}\ \sum\limits_{i = 1}^{\lfloor \frac{x}{p}\rfloor} \mu(i)\times F(i\times p)$ 
$=\sum\limits_{p\ \in\ Prime}\ \sum\limits_{i = 1}^{\lfloor \frac{x}{p}\rfloor} \mu(i)\times \lfloor \dfrac{n}{i \times p} \rfloor \times\lfloor \dfrac{m}{i \times p} \rfloor $ 
設$i \times p = k$ 
$=\sum\limits_{k= 1}^{n}\sum\limits_{p\ \in\ Prime , p|k}\mu(\dfrac{k}{p})\times \lfloor \dfrac{n}{k} \rfloor \times\lfloor \dfrac{m}{k} \rfloor $ 
$=\sum\limits_{k= 1}^{n} \lfloor \dfrac{n}{k} \rfloor \times\lfloor \dfrac{m}{k} \rfloor \times (\ \sum\limits_{p\ \in\ Prime , p|k}\mu(\dfrac{k}{p}))$
化完啦 
就可以上喜聞樂見的整體分塊啦!
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #define inc(i) (++ (i))
 6 #define dec(i) (-- (i))
 7 using namespace std;
 8 
 9 const int N = 10000000 + 7;
10 int n , Mu[N] , Prime[N] , cnt , A[N];
11 bool No_Prime[N];
12 long long Sum[N] , Ans;
13 
14 inline void Get_Mu(int n)
15 {
16     Mu[1] = 1;
17     for(int i = 2 ; i <= n ; inc(i))
18     {
19          if(!No_Prime[i])    Prime[inc(cnt)] = i , Mu[i] = -1;
20         for(int j = 1 ; j <= cnt && i * Prime[j] <= n ; inc(j))
21         {
22             No_Prime[i * Prime[j]] = 1;
23             if(i % Prime[j] == 0) break;
24             Mu[i * Prime[j]] = -Mu[i];
25         }
26     }
27     for(int j = 1 ; j <= cnt ; inc(j))
28         for(int i = 1 ;  i * Prime[j] <= n ; inc(i))
29             A[i * Prime[j]] += Mu[i];
30     for(int i = 1 ; i <= n ; inc(i))
31         Sum[i] = Sum[i - 1] + A[i];
32 }
33 
34 int main()
35 {
36     Get_Mu(10000000);
37     int T , n , m; scanf("%d" , &T);
38     while(T --)
39     {
40         scanf("%d%d" , &n , &m);
41         if(n > m) swap(n , m); 
42         Ans = 0;
43         for(int l = 1 , r ; l <= n ; l = r + 1)
44         {
45             r = min(n / (n / l) , m / (m / l));
46             Ans += 1ll * (n / l) * (m / l) * (Sum[r] - Sum[l - 1]);
47         }
48         printf("%lld\n" , Ans);
49     }
50     return 0;
51 }
luogu2257

 

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章