[BZOJ] 2705: [SDOI2012]Longge的问题

人生第一道自己做出来的数论题qwq..纪念一下

一开始复杂度不确定,和syq大兄弟讨论了一下才敢写

 

化简一下,枚举gcd然后计算其出现次数,发现g出现的次数就是phi(n/g),所以求的就是sigma(g*phi(n/g)*[g|n])

感觉这样搞是O(sqrt(n)*sqrt(n))=O(n)的,然而,一个数的质因数数量级在ln(n),因此是O(sqrt(n)ln(n))的,飞快。

 

#include<iostream>
#include<cstdio>

using namespace std;

typedef long long ll;

int phi(int x){
    int ret=x;
    for(int i=2;i*i<=x;i++){
        if(x%i==0){
            ret=ret/i*(i-1);
            while(x%i==0) x/=i;
        }
    }
    if(x!=1) ret=ret/x*(x-1);
    return ret;
}

int n;

int main(){
    cin>>n;
    long long ans=0;
    for(int i=1;i*i<=n;i++){
        if(n%i) continue;
        ans+=1ll*i*phi(n/i)+1ll*(n/i)*phi(i);
    }
    cout<<ans;
    return 0;
}

 

posted @ 2018-08-01 16:58  GhostCai  阅读(99)  评论(0编辑  收藏  举报