P3768 简单的数学题(莫比乌斯反演)
Posted lizehon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3768 简单的数学题(莫比乌斯反演)相关的知识,希望对你有一定的参考价值。
[题目链接] 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
",ans);
}
以上是关于P3768 简单的数学题(莫比乌斯反演)的主要内容,如果未能解决你的问题,请参考以下文章