Compute the Möbius function and

This article draws on the blog Mobius function and
the solution in this blog is the sum of the Mobius function in an interval segment, which can be calculated with a little modification

#include<bits/stdc++.h>
 
const int INF  = 0x3f3f3f3f;
const int Maxn = 1e7 * 2;
const int mod  = 2333333;
 
#define ll long long
#define mem(x,y) memset(x,y,sizeof(x))
using namespace std;
 
int pcnt = 0, prime[1300000]; // 质数
short  mu[Maxn];           //   莫比乌斯函数值
bool vis[Maxn];
 
void init() {
    
    
    mu[1] = 1;
    for (int i = 2; i < Maxn; i++) {
    
    
        if (vis[i] == 0) {
    
    
            mu[i] = -1;
            prime[++pcnt] = i;
        }
        for (int j = 1; j <= pcnt && i * prime[j] < Maxn; j++) {
    
    
            vis[i * prime[j]] = 1;
            if (i % prime[j] != 0)
                mu[i * prime[j]] = -mu[i];
            else {
    
    
                mu[i * prime[j]] = 0;
                break;
            }
        }
    }
 
    for (int i = 2; i < Maxn; i++) mu[i] += mu[i - 1];   //  函数前缀和
}
 
struct Hash {
    
    
    long long key;
    int value, next;
} node[mod];
int cnt = 0, Head[mod] = {
    
    0};
 
void Insert(long long N, int v) {
    
      // 记忆
    int ha = N % mod;
    node[++cnt].key = N;
    node[cnt].value = v;
    node[cnt].next = Head[ha];
    Head[ha] = cnt;
}
 
 
int M(long long N) {
    
    
    if (N < Maxn) return mu[N];
    int ha = N % mod;
    for (int i = Head[ha]; i != 0; i = node[i].next) {
    
      
        if (node[i].key == N)   // 如果已经计算过
            return node[i].value;
    }
    int  ans = 0;
    for (long long i = 2, j; i <= N; i = j + 1) {
    
    
        j = N / (N / i);   // 分块加速
        ans += (j - i + 1) * M(N / i);
    }
    Insert(N, 1 - ans);  // 做记忆
    return 1 - ans;
}
int main() {
    
    
    init();
    long long n;
    while (cin >> n) {
    
    
        cout << M(n) << endl;
    }
}


Guess you like

Origin blog.csdn.net/yzq199902/article/details/126160804