zoukankan      html  css  js  c++  java
  • 模板

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    //N为n^(2/3)最快
    int n;
    const int MAXN=5e6;
    
    unordered_map<int,int> Smu;
    unordered_map<int,ll> Sphi;
    
    ll sump[MAXN+5];
    int sumu[MAXN+5];
    int pri[MAXN+5],pritop;
    bool notpri[MAXN+5];
    //pritop从1开始计数
    
    void sieve(int n) {
        notpri[1]=sump[1]=sumu[1]=1;
        for(int i=2; i<=n; i++) {
            if(!notpri[i])
                pri[++pritop]=i,sump[i]=i-1,sumu[i]=-1;
            for(int j=1; j<=pritop&&i*pri[j]<=n; j++) {
                notpri[i*pri[j]]=1;
                //略有不同
                if(i%pri[j])
                    sump[i*pri[j]]=sump[i]*sump[pri[j]],sumu[i*pri[j]]=-sumu[i];
                else {
                    sump[i*pri[j]]=sump[i]*pri[j],sumu[i*pri[j]]=0;;
                    break;
                }
            }
        }
        for(int i=2; i<=n; i++) {
            sump[i]+=sump[i-1];
            sumu[i]+=sumu[i-1];
        }
    }
    
    //杜教筛莫比乌斯函数
    inline ll GetSumu(int n) {
        if(n <= MAXN)
            return sumu[n]; // sumu是提前筛好的前缀和
        if(Smu.count(n))
            return Smu[n]; // 记忆化
        ll ret = 1ll; // 单位元的前缀和就是 1
        for(int l = 2, r; r<2147483647&&l <= n; l = r + 1) {
            r = n / (n / l);
            ret -= (r - l + 1) * GetSumu(n / l);
            // (r - l + 1) 就是 I 在 [l, r] 的和
        }
        return Smu[n] = ret; // 记忆化
    }
    
    //杜教筛欧拉函数
    inline ll GetSphi(int n) {
        if(n <= MAXN)
            return sump[n]; // 提前筛好的
        if(Sphi.count(n)) return Sphi[n]; // 记忆化
        ll ret = n;
        if(ret%2==0)
            ret=(ret/2)* (1ll+n);
        else
            ret*=((1ll+n)/2);
        // f * g = id 的前缀和
        for(int l = 2, r; r<2147483647&&l <= n; l = r + 1) {
            r = n / (n / l);
            ret -= (r - l + 1) * GetSphi(n / l);
            // 同上,因为两个的 g 都是 I
        }
        return Sphi[n] = ret; // 记忆化
    }
    
    int main() {
        sieve(MAXN);
    
        int t;
        scanf("%d",&t);
        while(t--) {
            scanf("%d",&n);
            printf("%lld %lld
    ",GetSphi(n),GetSumu(n));
        }
    }
    
  • 相关阅读:
    [leetcode]Evaluate Division
    [leetcode]Read N Characters Given Read4 II
    [leetcode]Shortest Palindrome
    vim基础
    mac 默认设置python3最新版本环境变量
    mac 如何获取最高权限(关闭安全保护机制)
    mac 终端成功执行scrapy命令
    解决虚拟机VMware下ubuntu16.04LTS打不开软件中心Ubuntu Software
    解决虚拟机VMware下ubuntu16.04LTS异常连不上网
    SOA 服务架构之简介及理解
  • 原文地址:https://www.cnblogs.com/Inko/p/11747862.html
Copyright © 2011-2022 走看看