版权声明:写得不好,转载请通知一声,还请注明出处,感激不尽 https://blog.csdn.net/As_A_Kid/article/details/86655058
Problem
洛谷
求
Solution
为了方便表达,下文中约定
考虑把后面的式子莫反。设
,构造
反演得
把
代入
中,式子变为
前面数论分块,后面是一个积性函数,注意到 ,考虑杜教筛
不妨令后面的函数为 ,那么我们构造一个 。考虑它们的狄利克雷卷积
不妨令 ,就可以消掉 了,即 。
套用式子即可。
Code
#include <cstdio>
#include <map>
using namespace std;
typedef long long ll;
const int maxn=10000010,N=10000000;
template <typename Tp> inline int getmin(Tp &x,Tp y){return y<x?x=y,1:0;}
template <typename Tp> inline int getmax(Tp &x,Tp y){return y>x?x=y,1:0;}
template <typename Tp> inline void read(Tp &x)
{
x=0;int f=0;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
if(f) x=-x;
}
int mod,inv6,ans,tot,pri[1000010],phi[maxn];
ll n;
map<ll,int> ma;
map<ll,int>::iterator itr;
int pls(int x,int y){return x+y>=mod?x+y-mod:x+y;}
int dec(int x,int y){return x-y<0?x-y+mod:x-y;}
int sum(ll x){if(x>=mod) x%=mod;return (ll)x*(x+1)/2%mod;}
int sum2(ll x){if(x>=mod) x%=mod;return (ll)x*(x+1)%mod*(x+x+1)%mod*inv6%mod;}
int power(int x,int y)
{
int res=1;
for(;y;y>>=1,x=(ll)x*x%mod)
if(y&1)
res=(ll)res*x%mod;
return res;
}
void init()
{
phi[1]=1;inv6=power(6,mod-2);
for(int i=2;i<=N;i++)
{
if(!phi[i]) phi[i]=i-1,pri[++tot]=i;
for(int j=1;j<=tot&&i*pri[j]<=N;j++)
{
if(i%pri[j]==0)
{
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
phi[i*pri[j]]=phi[i]*(pri[j]-1);
}
}
for(int i=2;i<=N;i++) phi[i]=pls((ll)phi[i]*i%mod*i%mod,phi[i-1]);
}
int work(ll x)
{
if(x<=N) return phi[(int)x];
if((itr=ma.find(x))!=ma.end()) return itr->second;
int res=sum(x);res=(ll)res*res%mod;
for(ll i=2,j;i<=x;i=j+1)
{
j=x/(x/i);
res=dec(res,(ll)dec(sum2(j),sum2(i-1))*work(x/i)%mod);
}
return ma[x]=res;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
read(mod);read(n);
init();
for(ll i=1,j,tmp;i<=n;i=j+1)
{
j=n/(n/i);tmp=sum(n/i);tmp=(ll)tmp*tmp%mod;
ans=pls(ans,tmp*dec(work(j),work(i-1))%mod);
}
printf("%d\n",ans);
return 0;
}