莫比乌斯反演μ函数模板

参考学习:

https://blog.csdn.net/HowardEmily/article/details/78199037

https://blog.csdn.net/codeswarrior/article/details/81541972

O( n )筛法函数:

void init(){
    memset(prime,0,sizeof(prime));
    memset(mu,0,sizeof(mu));
    memset(vis,0,sizeof(vis));
    mu[1] = 1;
    cnt = 0;
    for(int i = 2; i < maxn; i++){
        if(!vis[i]){
            prime[cnt++] = i;
            mu[i] = -1;
        }
        for(int j = 0; j < cnt && i * prime[j] < maxn; j++){
            vis[i*prime[j]] = 1;
            if(i % prime[j]) mu[i*prime[j]] = -mu[i];
            else{
                mu[i*prime[j]] = 0;
                break;
            }
        }
    }
}

HDU 1695 GCD 反演经典入门:

http://acm.hdu.edu.cn/showproblem.php?pid=1695

扫描二维码关注公众号,回复: 5333281 查看本文章

Ac code:

 1 #include <bits/stdc++.h>
 2 #define INF 0x3f3f3f3f
 3 #define LL long long
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn = 1e5+7;
 7 bool vis[maxn];
 8 int prime[maxn],mu[maxn];
 9 int cnt;
10 void init(){
11     memset(prime,0,sizeof(prime));
12     memset(mu,0,sizeof(mu));
13     memset(vis,0,sizeof(vis));
14     mu[1] = 1;
15     cnt = 0;
16     for(int i = 2; i < maxn; i++){
17         if(!vis[i]){
18             prime[cnt++] = i;
19             mu[i] = -1;
20         }
21         for(int j = 0; j < cnt && i * prime[j] < maxn; j++){
22             vis[i*prime[j]] = 1;
23             if(i % prime[j]) mu[i*prime[j]] = -mu[i];
24             else{
25                 mu[i*prime[j]] = 0;
26                 break;
27             }
28         }
29     }
30 }
31 int main(){
32     init();
33     int T_case;
34     int a, b, c, d, k;
35     LL ans1 = 0, ans2 = 0;
36     scanf("%d", &T_case);
37     for(int Case = 1; Case <= T_case; Case++){
38         ans1 = 0; ans2 = 0;
39         printf("Case %d: ", Case);
40         scanf("%d %d %d %d %d", &a, &b, &c, &d, &k);
41         if(b < k || d < k || k == 0){
42             puts("0");
43             continue;
44         }
45         b = b/k;
46         d = d/k;
47         int len = min(b, d);
48         for(int i = 1; i <= len; i++){
49             ans1 += (LL)mu[i]*(b/i)*(d/i);
50         }
51         for(int i = 1; i <= len; i++){
52             ans2 += (LL)mu[i]*(len/i)*(len/i);
53         }
54         printf("%lld\n", ans1-ans2/2);
55     }
56     return 0;
57 }
View Code

猜你喜欢

转载自www.cnblogs.com/ymzjj/p/10440615.html
今日推荐