P3768 简单的数学题
莫反的做法不太会(有空来补)
\text{Solution}
因为
考虑枚举 d ,
观察到有
解决下
记
f,g均为积性函数。
然后杜教筛
\text{Code}
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <map>
#define N (int)(5e6+5)
#define ll long long
using namespace std;
int rd() {
int f=1,sum=0; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return sum*f;
}
ll lrd() {
ll f=1,sum=0; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return sum*f;
}
bool vis[N];
ll phi[N],mod,n,inv6;
int pri[N>>2],tot;
map<ll,ll>ans_phi;
ll fpow(ll x,ll y) {
ll res=1;
while(y) {
if(y&1) res=res*x%mod;
x=x*x%mod; y>>=1;
}
return res;
}
void init() {
phi[1]=1;
for(int i=2;i<N;i++) {
if(!vis[i]) pri[++tot]=i,phi[i]=i-1;
for(int j=1;j<=tot&&pri[j]*i<N;j++) {
vis[i*pri[j]]=1;
if(i%pri[j]==0) {
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
phi[i*pri[j]]=phi[i]*phi[pri[j]];
}
}
for(int i=1;i<N;i++) phi[i]=(phi[i]*i%mod*i%mod+phi[i-1])%mod;
}
ll SUM1(ll x) {
x%=mod;
return (x*(x+1ll)/2ll)%mod;
}
ll SUM2(ll x) {
x%=mod;
return x*(x+1)%mod*(2*x+1)%mod*inv6%mod;
}
ll SUM3(ll x) {
return SUM1(x)*SUM1(x)%mod;
}
ll get_phi(ll x) {
if(x<N) return phi[x];
if(ans_phi[x]) return ans_phi[x];
ll ans=SUM3(x);
for(ll l=2,r;l<=x;l=r+1) {
r=x/(x/l);
ans-=(SUM2(r)-SUM2(l-1)+mod)%mod*get_phi(x/l)%mod;
ans%=mod;
}
return ans_phi[x]=ans;
}
void solve() {
init(); inv6=fpow(6,mod-2);
ll ans=0;
for(ll l=1,r;l<=n;l=r+1) {
r=n/(n/l);
ans=(ans+SUM3(n/l)*(get_phi(r)-get_phi(l-1))%mod)%mod;
}
ans=(ans%mod+mod)%mod;
printf("%lld",ans);
}
int main() {
mod=lrd(); n=lrd();
solve();
return 0;
}