码迷,mamicode.com
首页 > 其他好文 > 详细

P3768 简单的数学题(莫比乌斯反演)

时间:2019-02-24 10:30:21      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:red   bre   typedef   inpu   最大   space   amp   lin   getchar   

[题目链接] https://www.luogu.org/problemnew/show/P3768

[题目描述]

\(\sum_{i=1}^{n}\sum_{j=1}^{n}i* j* gcd(i,j)\mod\ p\)

[欧拉反演题解] https://www.luogu.org/blog/zhoutb2333/solution-p3768

/*
-----------------------
最大测试点,时限6s
[Input]
1000000007 9786510294 
[Output]
27067954
-----------------------2019.2.24
*/
#include<bits/stdc++.h>
#include<tr1/unordered_map>
//#define int long long
using namespace std;
typedef long long LL;
const int INF=1e9+7;
inline LL read(){
    register LL x=0,f=1;register char c=getchar();
    while(c<48||c>57){if(c==‘-‘)f=-1;c=getchar();}
    while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
    return f*x;
}

const int MAXN=5e6+5;

int phi[MAXN],prime[MAXN];bool vis[MAXN];
LL sphi[MAXN];
LL n,mod,inv6,ans;
unordered_map <LL,LL> Sphi;

inline LL qpow(LL a,LL b){
    LL res=1;
    while(b){
        if(b&1) (res*=a)%=mod;
        (a*=a)%=mod;
        b>>=1;
    }
    return res;
}

inline void init(int n){
    phi[1]=1;
    for(int i=2;i<=n;i++){
        if(!vis[i]){
            prime[++prime[0]]=i;
            phi[i]=i-1;
        }
        int x;
        for(int j=1;j<=prime[0]&&(x=i*prime[j])<=n;j++){
            vis[x]=1;
            if(i%prime[j]==0){
                phi[x]=phi[i]*prime[j];
                break;
            }
            phi[x]=phi[i]*phi[prime[j]];
        }
    }
    for(int i=1;i<=n;i++){
        sphi[i]=(sphi[i-1]+1ll*phi[i]*i%mod*i%mod)%mod;
    }
}

inline LL s2(LL x){
    x%=mod;
    return x*(x+1)%mod*(2*x+1)%mod*inv6%mod;
}

inline LL s3(LL x){
    x%=mod;
    return ((x*(x+1)/2)%mod)*((x*(x+1)/2)%mod)%mod;
}

inline LL S_phi(LL n){
    if(n<MAXN) return sphi[n];
    if(Sphi[n]) return Sphi[n];
    LL res=s3(n);
    for(LL l=2,r;l<=n;l=r+1){
        r=n/(n/l);
        res=(res-(1ll*(s2(r)-s2(l-1)+mod)%mod*S_phi(n/l)%mod)+mod)%mod;
    }
    return Sphi[n]=res;
}

int main(){
    mod=read(),n=read();
    inv6=qpow(6,mod-2);
    init(MAXN-1);
    for(LL l=1,r;l<=n;l=r+1){
        r=n/(n/l);
        (ans+=1ll*(S_phi(r)-S_phi(l-1)+mod)%mod*s3(n/l)%mod)%=mod;
    }
    printf("%lld\n",ans);
}

P3768 简单的数学题(莫比乌斯反演)

标签:red   bre   typedef   inpu   最大   space   amp   lin   getchar   

原文地址:https://www.cnblogs.com/lizehon/p/10425369.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!