理论基础:
1、对n质因数分解,n=p1^k1 * p2^k2 * p3^k3 ……
则n的约数个数为(k1+1)*(k2+1)*(k3+1)……
2、线性筛素数时,用i和素数pj来筛掉 i*pj,
其中pj一定是i*pj的最小素因子
如果i是pj的倍数,pj也是i的最小素因子
设t[i] 表示i的约数个数,e[i] 表示i的最小素因子的个数
A、如果i是质数,t[i]=2,e[i]=1
B、如果i不是质数,枚举已有的质数pj
i*pj的最小素因子是pj
1、如果i是pj的倍数那么e[i]即为i中包含的pj的个数,所以i*pj中包含的pj的个数为e[i]+1
所以e[i*pj]=e[i]+1,t[i*pj]=t[i]/(e[i]+1)*(e[i]+2)
2、如果i不是pj的倍数,e[i*pj]=1,t[i*pj]=t[i]*t[pj](积性函数的性质)=t[i]*2(素数的约数个数=2)
#include<cstdio> using namespace std; #define N 1000001 bool vis[N]; int prime[N]; int t[N],e[N]; int main() { int n; scanf("%d",&n); int cnt=0; t[1]=1; for(int i=2;i<=n;++i) { if(!vis[i]) { prime[++cnt]=i; t[i]=2; e[i]=1; } for(int j=1;j<=cnt;++j) { if(i*prime[j]>n) break; vis[i*prime[j]]=true; if(i%prime[j]==0) { t[i*prime[j]]=t[i]/(e[i]+1)*(e[i]+2); e[i*prime[j]]=e[i]+1; break; } else { t[i*prime[j]]=t[i]*2; e[i*prime[j]]=1; } } } long long ans=0; for(int i=1;i<=n;++i) ans+=t[i]; printf("%lld",ans); }