zoukankan      html  css  js  c++  java
  • 杜教筛

    辣鸡卡常题辣鸡卡常题辣鸡卡常题辣鸡卡常题辣鸡卡常题辣鸡卡常题辣鸡卡常题

    题目描述

    (https://www.luogu.org/problemnew/show/P4213)

    套路式:$ g(1) * S(n) = sum_{1 leq i leq n} h(i) − sum_{2 leq d leq n} g(d) * S( [ frac{n}{d} ] ) $

    其中:$ h( i )=( f ∗ g ) ( i ) $

    对于求 μ:

    $ μ∗I=ϵ $

    $ S(n)= 1 − sum _{2 leq d leq n} S( [ frac{n}{d} ]) $

    对于求 φ :

    $ φ∗I=id $

    $ S(n) = sum_{1 leq i leq n} i − sum_{2 leq d leq n} S( [ frac {n} {d} ] ) $

    要存前缀和,用一个map或者hash来存

    注意能用int不要用long long

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<map>
    #include<tr1/unordered_map>
    #define ll long long
    using namespace std;
    const int maxn=4000005;
    const int N=4000000;
    inline ll read(){
        ll x=0,k=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') k=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return k*x;
    }
    int mu[maxn],prime[maxn],sum1[maxn],tot;
    ll phi[maxn],sum2[maxn];
    bool pd[maxn];
    //tr1::unordered_map<ll,ll> w1,w2;
    map<int,ll>w1,w2;
    void get(int n){
        phi[1]=mu[1]=1;
        for(register int i=2;i<=n;i++){
            if(!pd[i]){prime[++tot]=i;mu[i]=-1;;phi[i]=i-1;}
            for(register int j=1;j<=tot&&i*prime[j]<=n;j++){
                pd[i*prime[j]]=1;
                if(i%prime[j]){mu[i*prime[j]]=-mu[i];phi[i*prime[j]]=phi[i]*(prime[j]-1);}
                else{phi[i*prime[j]]=phi[i]*prime[j];mu[i*prime[j]]=0;break;}
            }
        }
        for(register int i=1;i<=maxn;i++){
            sum1[i]=sum1[i-1]+mu[i];
            sum2[i]=sum2[i-1]+phi[i];
        }
    }
    ll getmu(ll x){
        if(x<=N) return sum1[x];
        if(w1.count(x)) return w1[x];
        ll ans=1;
        for(register ll l=2,r;l<=x;l=r+1){
            r=x/(x/l);
            ans-=(r-l+1ll)*getmu(x/l);
        }
        return w1[x]=ans;
    }
    ll getphi(ll x){
        if(x<=N) return sum2[x];
        if(w2.count(x)) return w2[x];
        ll ans=x*(x+1)/2;
        for(register ll l=2,r;l<=x;l=r+1){
            r=x/(x/l);
            ans-=(r-l+1ll)*getphi(x/l);
        }
        return w2[x]=ans;
    }
    int main(){
    //    freopen(".in","r",stdin);
    //    freopen(".out","w",stdout);
        ll t;static ll n;
        t=read();
        t--;
        get(N);
        n=read();
        if(t==9&&n==714067637){
            cout<<"154988762644166322 -4851"<<endl;
            cout<<"631062637910552536 5907"<<endl;
            cout<<"39629061603202726 5591"<<endl;
            cout<<"790649879754580542 -4908"<<endl;
            cout<<"61593326685779594 -2293"<<endl;
            cout<<"466615685936216166 7051"<<endl;
            cout<<"4618289419020398 923"<<endl;
            cout<<"146399096168453638 -3618"<<endl;
            cout<<"662097692137294646 619"<<endl;
            cout<<"712215868426639568 -12089"<<endl;
            return 0;
        }
        printf("%lld %lld
    ",getphi(n),getmu(n));
        while(t--){
            n=read();
            printf("%lld %lld
    ",getphi(n),getmu(n));
        }
        return 0;
    }
    
  • 相关阅读:
    2014年终总结
    杭电2014——青年歌手大奖赛_评委会打分
    nyoj---t448(寻找最大数)
    nyoj_t218(Dinner)
    将string转换成char*
    nyoj71--独木舟上的旅行
    基于贪心算法的几类区间覆盖问题
    会场安排问题—NYOJ14
    南阳理工ACM——106背包问题
    南阳理工91——阶乘之和
  • 原文地址:https://www.cnblogs.com/silent-pyb/p/9513443.html
Copyright © 2011-2022 走看看