求助/kel
查看原帖
求助/kel
160839
Prean楼主2020/10/20 21:55

Min25 板子照着第一篇题解改的,样例1一直输出137,求助/kel

#include<cstdio>
#include<cmath>
typedef long long ll;
const int St=1e6,mod=1e9+7,inv3=333333336;
int sqr,top,tot,zhi[St];
ll n,w[St],g1[St],g2[St],pri[St],id1[St],id2[St],sum1[St],sum2[St];
inline int Add(const int&a,const int&b){
    return a+b>=mod?a+b-mod:a+b;
}
inline int Get(const int&k){
	return k<=sqr?id1[k]:id2[n/k];
}
inline void seive(const int&n){
    int i,j,x;zhi[1]=1;
    for(i=2;i<=n;++i){
        if(!zhi[i]){
            pri[++top]=i;
            sum1[top]=Add(sum1[top-1],i);
            sum2[top]=Add(sum2[top-1],1ll*i*i%mod);
        }
        for(j=1;j<=top&&(x=i*pri[j])<=n;++j){
            zhi[x]=1;
            if(!(i%pri[j]))break;
        }
    }
}
ll S(const ll&n,const int&k){
    if(pri[k]>=n)return 0;
    ll x=Get(k),ans=Add((g2[x]-g1[x]+sum1[k]-sum2[k])%mod,mod);
    for(int i=k+1;i<=top&&pri[i]*pri[i]<=n;++i){
        ll p=pri[i];
        for(int e=1;p<=n;++e,p*=pri[i]){
            ll id=p%mod;
            ans=Add(ans,id*(id-1)%mod*((e!=1)+S(n/p,i))%mod);
        }
    }
    return ans;
}
ll min_25(const ll&n){
    int i,j;
    seive(sqr=sqrt(n));
    for(ll L=1,R;L<=n;L=R+1){
        R=n/(n/L);
        w[++tot]=n/L;
        g1[tot]=w[tot]%mod;
        g2[tot]=g1[tot]*(g1[tot]+1)/2%mod*(g1[tot]*2+1)%mod*inv3%mod-1;
        g1[tot]=g1[tot]*(g1[tot]+1)/2%mod-1;
        if(n/L<=sqr)id1[n/L]=tot;
        else id2[n/(n/L)]=tot;
    }
    for(i=1;i<=top;++i){
        for(j=1;j<=tot&&1ll*pri[i]*pri[i]<=w[j];++j){
            ll k=Get(w[j]/pri[i]);
            g1[j]-=pri[i]*(g1[k]-sum1[i-1]+mod)%mod;
            g2[j]-=pri[i]*pri[i]%mod*(g2[k]-sum2[i-1]+mod)%mod;
            if(g1[j]<=0)g1[j]+=mod;
            if(g2[j]<=0)g2[j]+=mod;
        }
    }
    return Add(S(n,0),1);
}
signed main(){
    scanf("%lld",&n);
    printf("%d",min_25(n));
}
2020/10/20 21:55
加载中...