Project Euler 675
题目
Let denote the number
of distinct prime divisors of a positive integer .
So and .
Let be .
E.g. .
Let .
.
Find . Give your
answer modulo .
解决方案
假设 的分解为 。
根据 函数的定义,当 时,有 ,并且,.
对于函数 而言,意味着每一项的 可以写成 。那么考虑 的某个质因数分量 ,那么发现, 中的每个和式包含了 中的某一个项,并且发现这些项跟除 以外的所有项都是一一组合。因此考虑将上面的这些项加起来,得到 。
将每个分量进行同样的操作,最终得到 。
由于本题计算的是 的前缀和,因此从小到大枚举 ,并对 进行分解质因数。在整个过程中,用一个数组维护 的分解质因数的结果,在此过程维护 的值。对于单独的一个 ,如果使用线性逆元,那么维护成本为 。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| # include <bits/stdc++.h> # define pi pair<int,int> using namespace std; typedef long long ll; const int N=10000000; const int M=2*N+1; ll mod=1000000087; int pr[N/10+100],v[N+4],m=0; int e[N+4]; ll inv[M+4]; int a[14],b[14],o=0; void fact(int n){ o=0; for(;n!=1;){ a[++o]=v[n]; b[o]=0; for(;n%a[o]==0;n/=a[o],++b[o]); } } int main(){ for(int i=2;i<=N;i++){ if(v[i]==0) pr[++m]=i,v[i]=i; for(int j=1;j<=m;j++){ if(pr[j]>v[i]||pr[j]>N/i) break; v[i*pr[j]]=pr[j]; } } inv[1]=1; for(int i=2;i<=M;i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod; ll ans=0,v=1; for(int i=2;i<=N;i++){ fact(i); for(int j=1;j<=o;j++){ v=v*inv[2*e[a[j]]+1]%mod; e[a[j]]+=b[j]; v=v*(2*e[a[j]]+1)%mod; } ans=(ans+v)%mod; } printf("%lld\n",ans);
}
|