@xiaoziyao
2020-05-04T04:39:00.000000Z
字数 4845
阅读 1603
解题报告
简单的数学题解题报告:
题意:求
数据范围:且,保证为质数
做这道题前,请保证你已经学会莫比乌斯反演和杜教筛0,否则可以到我博珂里康康:
狄利克雷卷积&莫比乌斯反演学习笔记
杜教筛学习笔记
开始推式子:
代码:
#include<stdio.h>#include<map>using namespace std;const long long maxn=5000005;long long i,j,k,m,n,mod,cnt,inv6;long long a[maxn],p[maxn],varphi[maxn],S[maxn];map<long long,long long>ans;inline long long getsum(long long n){return n*(n+1)/2%mod;}inline long long calc(long long n){return n*(n+1)%mod*(2*n+1)%mod*inv6%mod;}long long ksm(long long a,long long b,long long mod){long long res=1;while(b){if(b&1)res=(res*a)%mod;a=(a*a)%mod,b>>=1;}return res;}long long getS(long long n){if(n<maxn)return S[n];if(ans.count(n))return ans[n];long long l=2,r,res=getsum(n)*getsum(n)%mod;while(l<=n){r=n/(n/l);res=((res-(calc(r)-calc(l-1)+mod)%mod*getS(n/l)%mod)%mod+mod)%mod;l=r+1;}res=(res%mod+mod)%mod;return ans[n]=res;}long long getans(long long n){long long l=1,r,res=0;while(l<=n){r=n/(n/l);res=(res+(getS(r)-getS(l-1)+mod)%mod*getsum(n/l)%mod*getsum(n/l)%mod)%mod;l=r+1;}res=(res%mod+mod)%mod;return res;}int main(){scanf("%lld%lld",&mod,&n);inv6=ksm(6,mod-2,mod);p[1]=varphi[1]=1;for(i=2;i<maxn;i++){if(p[i]==0)a[++cnt]=i,varphi[i]=i-1;for(j=1;j<=cnt;j++){if(i*a[j]>=maxn)break;p[i*a[j]]=1;if(i%a[j]==0){varphi[i*a[j]]=varphi[i]*a[j];break;}varphi[i*a[j]]=varphi[i]*(a[j]-1);}}for(i=1;i<maxn;i++)S[i]=(S[i-1]+varphi[i]%mod*i%mod*i%mod)%mod;printf("%lld\n",getans(n));return 0;}
