常数巨大+取模错误PN筛求调
查看原帖
常数巨大+取模错误PN筛求调
590600
Kreado楼主2023/5/1 11:08

什么鬼,常数巨大PN筛,取模也错了

#include <bits/stdc++.h>
#define ll long long
#define lll __int128
using namespace std;
const ll Mod=1e9+7,Maxn=1e7+7,inv6=166666668,inv2=500000004;
ll n;
ll phi[Maxn],g[Maxn];
ll ans;
ll G[Maxn];
ll prime[Maxn],cnt;
bool isprime[Maxn];
inline void print(lll x){
    if(x>9) print(x/10);
    putchar('0'+x%10);
}
inline void init(ll N){
    isprime[1]=1;phi[1]=1;
    for(ll i=2;i<=N;i++){
        if(!isprime[i]) prime[++cnt]=i,phi[i]=i-1;
        for(ll j=1;j<=cnt&&prime[j]*i<=N;j++){
            isprime[i*prime[j]]=1;
            if(!(i%prime[j])){
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            phi[i*prime[j]]=phi[i]*(prime[j]-1);
        }
    }
    for(ll i=1;i<=N;i++) g[i]=(g[i-1]+phi[i]*i%Mod)%Mod,g[i]=(g[i]%Mod+Mod)%Mod;
}
inline lll f2(ll x){
    x%=Mod;
    return x%Mod*(x+1)%Mod*(2*x+1)%Mod*inv6%Mod;
}
inline ll calc(ll x){
    if(x<=Maxn-7) return g[x];
    if(G[n/x]) return G[n/x];
    ll res=f2(x);res=(res%Mod+Mod)%Mod;
    for(ll l=2,r;l<=x;l=r+1){
        r=x/(x/l);
        ll t=(r-l+1)%Mod*(l+r)%Mod*inv2%Mod;
        res=((res-t*calc(x/l)%Mod)%Mod+Mod)%Mod;
    }
    res=(res%Mod+Mod)%Mod;
    return G[n/x]=res;
}
void GetPN(ll k,ll m,ll h){
    if(k>cnt||m*prime[k]>n){
        if(n/m<=Maxn-7) ans=(ans+h%Mod*g[n/m]%Mod)%Mod;
        else ans=(ans+h%Mod*G[n/(n/m)]%Mod)%Mod;
        ans=(ans%Mod+Mod)%Mod;
        return ;
    }
    ll p=1ll*prime[k]*prime[k];
    GetPN(k+1,m,h);
    for(ll i=2;m*p<=n;p*=prime[k],i++)
        GetPN(k+1,m*p,p%Mod*(prime[k]-1)%Mod*(i-1)%Mod*h%Mod);
} 
int main(){
    scanf("%lld",&n);
    init(Maxn-7);
    calc(n);
    GetPN(1,1,1);
    print(ans);
    return 0;
}
2023/5/1 11:08
加载中...