求助90分
查看原帖
求助90分
32275
KesdiaelKen楼主2018/5/22 20:29
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<iostream>
#include<queue>
#include<ctime>
#include<cstdlib>
#include<map>
using namespace std;
long long p,n;
long long phi[10000010];
bool vis[10000010]={0};long long pri[10000010]={0},gs=0;
long long sum[10000010]={0};
map<long long,long long>getsum;
void init()
{
    phi[1]=1;
    for(long long i=2;i<=8000000;i++)
    {
        if(!vis[i])pri[++gs]=i,phi[i]=i-1;
        for(long long j=1;j<=gs&&i*pri[j]<=8000000;j++)
        {
            vis[i*pri[j]]=true;
            if(i%pri[j]==0)
            {
                phi[i*pri[j]]=phi[i]*pri[j]%p;
                break;
            }
            phi[i*pri[j]]=phi[i]*(pri[j]-1)%p;
        }
    }
    for(long long i=1;i<=8000000;i++)sum[i]=(sum[i-1]+phi[i]*i%p*i%p)%p;
}
long long x,y4,y6;
void exgcd(long long a,long long b,long long&x,long long&y)
{
    if(b==0){x=1;y=(long long)0;return;}
    exgcd(b,a%b,y,x);y-=a/b*x;
}
long long cal_2(long long a)
{
    return a%p*(a+1)%p*(2*a%p+1)%p*y6%p;
}
long long cal_3(long long a)
{
    return a%p*a%p*(a+1)%p*(a+1)%p*y4%p;
}
long long qsum(long long a)
{
    if(a<=8000000)return sum[a];
    if(getsum.count(a))return getsum[a];
    long long he=0;
    for(long long zuo=2,you;zuo<=a;zuo=you+1)
    {
        you=a/(a/zuo);
        he=((he+(cal_2(you)-cal_2(zuo-1))%p*qsum(a/zuo)%p)%p+p)%p;
    }
    getsum[a]=((cal_3(a)-he)%p+p)%p;
    return getsum[a];
}
int main()
{
    scanf("%lld%lld",&p,&n);
    init();
    exgcd(p,4,x,y4);
    exgcd(p,6,x,y6);
    y4=(y4%p+p)%p;
    y6=(y6%p+p)%p;
    long long he=0;
    for(long long zuo=1,you;zuo<=n;zuo=you+1)
    {
        you=n/(n/zuo);
        he=(he+(y4*(n/zuo)%p*(n/zuo)%p*(n/zuo+1)%p*(n/zuo+1)%p*(qsum(you)-qsum(zuo-1))%p+p)%p+p)%p;
    }
    printf("%lld\n",he);
    return 0;
}
2018/5/22 20:29
加载中...