WA三个点
查看原帖
WA三个点
531223
gbk002SNake楼主2021/8/31 15:20
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int md=1e9+7;
const int MA=2e5+10;
const int inv2=(md+1)/2;
const int inv3=333333336;
const int inv6=166666668;
int nn,cnt,tot,sr;
int vis[MA],sp1[MA],sp2[MA],prm[MA],g1[MA],g2[MA],ind1[MA],ind2[MA],w[MA];

void getprime(int n)
{
    vis[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(!vis[i])
        {
            prm[++cnt]=i;
            sp1[cnt]=(sp1[cnt-1]+i)%md;
            sp2[cnt]=(sp2[cnt-1]+i*i)%md;
        }
        for(int j=1;j<=cnt&&i*prm[j]<=n;j++)
        {
            vis[i*prm[j]]=1;
            if(!i%prm[j])break;
        }
    }
}

void G1()
{ 
 for(int i=1;i<=nn;)
    {
        int j=nn/(nn/i);
        w[++tot]=nn/i;
        g1[tot]=w[tot]%md;
        g2[tot]=g1[tot]*(g1[tot]+1)/2%md*(2*g1[tot]+1)%md*inv3%md;
        g2[tot]--;
        g1[tot]=g1[tot]*(g1[tot]+1)/2%md-1;
        if(nn/i<=sr)ind1[nn/i]=tot;
        else ind2[nn/(nn/i)]=tot;
        i=j+1;
    }


  
    for(int i=1;i<=cnt;i++)
    {
        for(int j=1;j<=tot&&prm[i]*prm[i]<=w[j];j++)
        {
            int k=(w[j]/prm[i])<=sr?ind1[w[j]/prm[i]]:ind2[nn/(w[j]/prm[i])];
            g1[j]-=prm[i]*(g1[k]-sp1[i-1]+md)%md;
            g2[j]-=prm[i]*prm[i]*(g2[k]-sp2[i-1]+md)%md;
            g1[j]%=md;
            g2[j]%=md;
            if(g1[j]<0)g1[j]+=md;
            if(g2[j]<0)g2[j]+=md;
        }
    }
}

int S(int x,int y)
{
    if(prm[y]>=x)return 0;
    int k=x<=sr?ind1[x]:ind2[nn/x];
    int ans=(g2[k]-g1[k]+md-(sp2[y]-sp1[y])+md)%md;
    for(int i=y+1;i<=cnt&&prm[i]*prm[i]<=x;i++)
    {
        int pe=prm[i];
        for(int e=1;pe<=x;e++,pe=pe*prm[i])
        {
            int xx=pe%md;
            ans=(ans+xx*(xx-1)%md*(S(x/pe,i)+(e!=1)))%md;
        }
    }
    return ans%md;
}

signed main()
{
    cin>>nn;
    sr=sqrt(nn);
    getprime(sr);
    G1();
    cout<<(S(nn,0)+1)%md<<'\n';
    return 0;
}

改来改去几乎都成照着第一篇题解抄了。。。还是不对,崩溃

2021/8/31 15:20
加载中...