Description
题目描述
定义积性函数 $f(x)$ ,且 $f(p^k)=p^k(p^k-1)$ ($p$ 是一个质数),求
$$\sum_{i=1}^n f(i)$$
对$10^9+7$取模。
输入格式
一行一个整数 $n$ 。
Solution
洛谷题解里的大佬们讲得很清楚了
扫描二维码关注公众号,回复:
9467432 查看本文章
但蒟蒻还是花了好长时间才搞懂。。。awsl
程序运行时容易超精度,多%几下
Code
#include <cstdio> #include <cstdlib> #include <cmath> #define ll long long using namespace std; const int N=1e6+10; const ll P=1e9+7; int vis[N],tot,cnt,ind1[N],ind2[N]; ll sp1[N],sp2[N],w[N],g1[N],n,g2[N],inv3=333333336,prime[N],sq; void pre() { for(int i=2;i<=sq;i++)//线性筛根号n内质数 { if(!vis[i]) { prime[++tot]=i; sp1[tot]=(sp1[tot-1]+prime[tot])%P; sp2[tot]=(sp2[tot-1]+prime[tot]*prime[tot]%P)%P; } for(int j=1;j<=tot && prime[j]<=sq/i;j++) { vis[prime[j]*i]=1; if(i%prime[j]==0) break; } } } ll S(ll x,int y) { if(prime[y]>=x) return 0; ll k=x<=sq?ind1[x]:ind2[n/x]; ll ans=(g2[k]-g1[k]-sp2[y]+sp1[y])%P; for(int i=y+1;i<=tot && prime[i]<=x/prime[i];i++) { ll now=prime[i]; for(int j=1;now<=x;j++,now=now*prime[i]) { ll xx=now%P; ans=(ans+xx*(xx-1)%P*(S(x/now,i)+(j!=1)))%P; } } return ans; } int main() { scanf("%lld",&n); sq=sqrt(n); pre(); for(ll l=1,r;l<=n;l=r+1)//处理可能用到的g { r=n/(n/l); w[++cnt]=n/l;//离散可能用到的g,随着cnt增加w[cnt]依次减小 g1[cnt]=w[cnt]%P; //初始化g函数,即求g(i,0) g2[cnt]=g1[cnt]*(g1[cnt]+1)/2%P*(2*g1[cnt]+1)%P*inv3%P-1;//求前(n/l)个数的平方和 g1[cnt]=g1[cnt]*(g1[cnt]+1)/2%P-1;//求前(n/l)个数的和 if(n/l<=sq) ind1[n/l]=cnt; else ind2[n/(n/l)]=cnt;//哈希 } for(int i=1;i<=tot;i++)//dp,滚动优化掉g的第二维 for(int j=1;j<=cnt && prime[i]<=w[j]/prime[i];j++) { ll x=w[j]/prime[i]; int k=(x<=sq)?ind1[x]:ind2[n/x]; g1[j]=(g1[j]-prime[i]*(g1[k]-sp1[i-1])%P)%P; g2[j]=(g2[j]-prime[i]*prime[i]%P*(g2[k]-sp2[i-1])%P)%P; } printf("%lld\n",(S(n,0)+1+P)%P); return 0; }