求助
  • 板块学术版
  • 楼主ImmortalWatcher
  • 当前回复0
  • 已保存回复0
  • 发布时间2020/8/30 17:33
  • 上次更新2023/11/5 13:57:01
查看原帖
求助
157857
ImmortalWatcher楼主2020/8/30 17:33

Min_25Min\_25 筛板子70,最后3个点挂了。

#include<cstdio>
#include<cmath>
const long long mo=1e9+7;
long long n,w[200010],tot;
int qt,prime[100010],cnt,gp1[100010],gp2[100010],g1[200010],g2[200010],id1[100010],id2[100010];
bool v[100010];
inline int S(long long x,int y)
{
    if (prime[y]>=x) return 0;
    int p=x<=qt?id1[x]:id2[n/x];
    int ans=((0ll+g2[p]-g1[p]-(gp2[y]-gp1[y]))%mo+mo)%mo;
    for (int i=y+1;i<=cnt;i++)
	{
		if (1ll*prime[i]*prime[i]>x) break;
        long long pe=prime[i];
        for (int e=1;pe<=x;e++,pe*=prime[i])
		{
            int o=pe%mo;
            ans=(ans+1ll*o*(o-1)%mo*(S(x/pe,i)+(e!=1)))%mo;
        }
    }
    return ans;
}
int main()
{
    scanf("%d",&n);
	qt=sqrt(n);v[1]=true;
    for (int i=2;i<=qt;i++)
	{
        if (!v[i]) prime[++cnt]=i;
        for (int j=1;j<=cnt;j++)
		{
			if (i*prime[j]>qt) break;
            v[i*prime[j]]=true;
            if (i%prime[j]==0) break;
        }
    }
    for (int i=1;i<=cnt;i++)
		gp1[i]=(gp1[i-1]+prime[i])%mo,gp2[i]=(gp2[i-1]+1ll*prime[i]*prime[i])%mo;
    for (long long l=1,r;l<=n;l=r+1)
	{
        r=n/(n/l);w[++tot]=n/r;
        g1[tot]=w[tot]%mo;
        g2[tot]=(1ll*g1[tot]*(g1[tot]+1)%mo*(g1[tot]*2+1)%mo*166666668%mo-1)%mo;
        g1[tot]=(1ll*g1[tot]*(g1[tot]+1)%mo*500000004-1)%mo;
        if(n/r<=qt) id1[n/r]=tot;else id2[r]=tot;
    }
    for (int i=1;i<=cnt;i++)
	{
    	for (int j=1;j<=tot;j++)
		{
			if (1ll*prime[i]*prime[i]>w[j]) break;
            long long p=w[j]/prime[i];
            p=(p<=qt?id1[p]:id2[n/p]);
            g1[j]=(g1[j]-1ll*prime[i]*(g1[p]-gp1[i-1]+mo)%mo+mo)%mo;
            g2[j]=(g2[j]-1ll*prime[i]*prime[i]%mo*(g2[p]-gp2[i-1]+mo)%mo+mo)%mo;
        }
    }
    printf("%d\n",(S(n,0)+1)%mo);
    return 0;
}
2020/8/30 17:33
加载中...