bzoj2705(洛谷P2303): [SDOI2012]Longge的问题 (欧拉函数)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sunshiness_s/article/details/81361973

题意

i = 1 n g c d ( i , n )


题解

这题…真的要写一下了…
其实吧,结果就是 i | n i φ ( n i )
然后!怎么求 v a r p h i
这里给出一个超级厉害的做法!线筛+杜教筛!

当然如果你信了的话呢,咱们握握手吧!

直接求复杂度就是 n 呀..很..赞..的!


代码

//正解!
#include <cstdio>
#include <cmath>
#define ll long long
ll n,ans;
ll phi(ll x){
    ll t=x;
    for(ll i=2;i<=sqrt(n);i++){
        if(x%i==0){
            t=t/i*(i-1);
            while(x%i==0) x/=i;
        }
    }
    if(x>1) t=t/x*(x-1);
    return t;
}
int main(){
//  freopen("a.in","r",stdin);
    scanf("%lld",&n);
    for(int i=1;i<=sqrt(n);i++){
        if(n%i==0){
            ans+=(ll)i*phi(n/i);
            ll x=n/i;
            if(i!=x) ans+=(ll)x*phi(n/x);
        }
    }
    printf("%lld\n",ans);
    return 0;
}
//傻子版!
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <algorithm>
using namespace std;
#define ll long long
#define N 2000010
#define U unsigned int
ll ans=0,phi[N],s1[N];
int n,tot,notprime[N],prime[N];
inline void euler(){
    phi[1]=1;
    for(int i=2;i<=2000000;i++){
        if(!notprime[i]) prime[++tot]=i,phi[i]=i-1;;
        for(int j=1;j<=tot && prime[j]*i<=2000000;j++){
            notprime[prime[j]*i]=1;
            if(i%prime[j]==0){
                phi[prime[j]*i]=phi[i]*prime[j];
                break;
            }phi[prime[j]*i]=phi[i]*phi[prime[j]];
        }
    }
    for(int i=2;i<=2000000;i++) phi[i]+=phi[i-1];
}
map<int,ll>mp;
inline ll calc(int x){
    if(x<=2000000) return phi[x];
    if(mp[x]) return mp[x];
    ll res=(ll)x*(x+1)>>1;
    for(U i=2,last;i<=x;i=last+1){
        last=x/(x/i);
        res-=calc(x/i)*(last-i+1);
    }mp[x]=res;
    return res;
}
int main(){
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    scanf("%d",&n);
    euler();memset(s1,0,sizeof(s1));
    for(int i=1;i<=sqrt(n);i++){
        if(n%i==0) ans+=(calc(n/i)-calc(n/i-1))*i;
        int x=n/i;
        if(n%x==0 && x!=i) ans+=(calc(n/x)-calc(n/x-1))*x;
    }
    printf("%lld",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunshiness_s/article/details/81361973