• BZOJ 3944 杜教筛


    思路:

    杜教筛裸题

    //By SiriusRen
    #include <map>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=5000050;
    typedef long long ll;
    int prime[N],vis[N],mu[N],maxx=5000000,tot,n,cases;
    ll phi[N];
    map<int,ll>_phi,_mu;
    map<int,ll>::iterator it;
    void shai(){
        mu[1]=phi[1]=1;
        for(int i=2;i<=maxx;i++){
            if(!vis[i])prime[++tot]=i,mu[i]=-1,phi[i]=i-1;
            for(int j=1;j<=tot&&i*prime[j]<=maxx;j++){
                vis[i*prime[j]]=1,mu[i*prime[j]]=-mu[i],phi[i*prime[j]]=phi[i]*(prime[j]-1);
                if(i%prime[j]==0){
                    mu[i*prime[j]]=0,phi[i*prime[j]]=phi[i]*prime[j];
                    break;
                }
            }
            mu[i]+=mu[i-1],phi[i]+=phi[i-1];
        }
    }
    ll get_phi(ll x){
        if(x<=maxx)return phi[x];
        if((it=_phi.find(x))!=_phi.end())return it->second;
        ll re=1ll*x*(x+1)/2;
        for(ll i=2,last;i<=x;i=last+1){
            last=x/(x/i);
            re-=(last-i+1)*get_phi(x/i);
        }return _phi[x]=re;
    }
    int get_mu(ll x){
        if(x<=maxx)return mu[x];
        if((it=_mu.find(x))!=_mu.end())return it->second;
        int re=1;
        for(ll i=2,last;i<=x;i=last+1){
            last=x/(x/i);
            re-=(last-i+1)*get_mu(x/i);
        }return _mu[x]=re;
    }
    signed main(){
        shai();
        scanf("%d",&cases);
        while(cases--){
            scanf("%d",&n);
            printf("%lld %d
    ",get_phi(n),get_mu(n));
        }
    }
    

      

  • 相关阅读:
    HDU 1856 More is better
    并查集模板
    HDU 1325 Is It A Tree?
    HDU 1272 小希的迷宫
    CodeVS 2639 约会计划
    POJ 1163 数字三角形
    HDU 1232 畅通工程
    HDU 1213 How Many Tables
    树形结构打印二叉树
    网址收藏
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6685535.html
Copyright © 2020-2023  润新知