版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Myriad_Dreamin/article/details/82533698
定义一个函数
问 的值.
运用交换主元的方法:
运用容斥就可以求出两项和式,单次复杂度由下式给出
不会解,但是很容易知道这个式子是不太超过 量级的。
啊啊啊,怎么这么简单!考试没做真可惜了。
#include <cstdio>
const int N=100005,lgN=20;
int np[N+5],prim[N/(lgN-5)],ptop=0;
void sieve(){
for(int i=2;i<=N;i++){
if(np[i])continue;
prim[ptop++]=i;
for(int j=i+i;j<=N;j+=i)np[j]=1;
}
}
long long n,p;
inline long long mul(long long x,long long y){
long long tmp=(x*y-(long long)((long double)x/p*y+1.0e-8)*p);
return tmp<0?tmp+p:tmp;
}
inline long long cal2(long long n){
long long n2=n+1,n3=2*n+1;
if((n&1)==0)n>>=1;else n2>>=1;
if((n%3==0))n/=3;else if(n2%3==0)n2/=3;else n3/=3;
return mul(n,mul(n2,n3));
}
inline long long cal3(long long n){
long long n2=n,n3=n+1,n4=n+1;
if((n&1)==0)n>>=1,n2>>=1;
else n3>>=1,n4>>=1;
return mul(mul(n,n2),mul(n3,n4));
}
long long inc2(long long x,int dep){
long long res=0,pri=(long long)prim[dep]*prim[dep],t;
for(int i=dep;pri<=x;i++,pri=(long long)prim[i]*prim[i]){
t=mul(pri,pri);
res+=mul(t,cal2(x/pri)-inc2(x/pri,i+1)+p);
}
return res;
}
long long inc3(long long x,int dep){
long long res=0,pri=(long long)prim[dep]*prim[dep],t;
for(int i=dep;pri<=x;i++,pri=(long long)prim[i]*prim[i]){
t=mul(pri,mul(pri,pri));
res+=mul(t,cal3(x/pri)-inc3(x/pri,i+1)+p);
}
return res;
}
int main(){
sieve();
while(~scanf("%lld%lld",&n,&p)){
long long res=mul(n+1,(cal2(n)-inc2(n,0)+p)%p)-(cal3(n)-inc3(n,0))%p+p;
printf("%lld\n",res%p);
}
}