Divisors of the Divisors of An Integer
题意:
给定两个函数 d ( n ) 和 s n d d ( n ) d(n)和sndd(n) d(n)和sndd(n), d ( n ) d(n) d(n)为n的因子个数, s n d d ( n ) sndd(n) sndd(n)为n的因子的 d ( x ) d(x) d(x)和。例如: s n d d ( 24 ) = d ( 1 ) + d ( 2 ) + d ( 3 ) + d ( 4 ) + d ( 6 ) + d ( 8 ) + d ( 12 ) + d ( 24 ) = 30 sndd(24)=d(1)+d(2)+d(3)+d(4)+d(6)+d(8)+d(12)+d(24)=30 sndd(24)=d(1)+d(2)+d(3)+d(4)+d(6)+d(8)+d(12)+d(24)=30
求 s n d d ( n ! ) sndd(n!) sndd(n!), n ! = 1 × 2 × 3 × . . . × n n!=1\times2\times3\times...\times n n!=1×2×3×...×n
思路:
根据唯一分解定理:
n
!
=
p
1
a
1
×
p
2
a
2
×
p
3
a
3
×
.
.
.
×
p
x
a
x
n!=p_1^{a_1}\times p_2^{a_2} \times p_3^{a_3}\times ...\times p_x^{a_x}
n!=p1a1×p2a2×p3a3×...×pxax
所以n的所有因子可以表示为:
n
′
=
p
1
b
1
×
p
2
b
2
×
p
3
b
3
×
.
.
.
×
p
x
b
x
,
其
中
0
≤
b
i
≤
a
i
n'=p_1^{b_1}\times p_2^{b_2} \times p_3^{b_3}\times ...\times p_x^{b_x},其中0\le b_i \le a_i
n′=p1b1×p2b2×p3b3×...×pxbx,其中0≤bi≤ai
所以对于每一个
b
i
b_i
bi都有
a
i
+
1
a_i+1
ai+1种取值。由于
p
i
p_i
pi为素数,所以
d
(
p
i
x
)
=
x
+
1
d(p_i^{x})=x+1
d(pix)=x+1。
在计算答案的时候我们可以计算每一个质因子对答案的贡献。那对于 p 1 p_1 p1这个质因子,它的贡献不就是 d ( p 1 0 ) + d ( p 1 1 ) + . . . + d ( p 1 a 1 ) = ( a 1 + 1 ) + a 1 × ( a 1 + 1 ) 2 d(p_1^0)+d(p_1^1)+...+d(p_1^{a_1})=(a_1+1)+ \cfrac{a_1\times(a_1+1)}{2} d(p10)+d(p11)+...+d(p1a1)=(a1+1)+2a1×(a1+1)
所以最后的答案不就是 ∏ ( a i + 1 ) + a i × ( a i + 1 ) 2 \prod (a_i+1)+ \cfrac{a_i\times(a_i+1)}{2} ∏(ai+1)+2ai×(ai+1)
那n!的所有质因子个数如何求呢?
如果要你算n!中有多少个因子x,那么结果就是n/x的累加。------这是个结论
参考代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll M=10000007;
const int maxn=1e6+10;
ll prime[maxn];
bool vis[maxn];
ll cnt;
void Prime()
{
for (int i = 2; i < maxn; i++)
{
if (vis[i] == false) prime[cnt++] = i;
for (int j = 0; i * prime[j] < maxn; j++)
{
vis[i * prime[j]] = true;
if (i % prime[j] == 0) break;
}
}
}
int main()
{
Prime();
ll n;
while(~scanf("%lld",&n))
{
if(n==0)break;
ll ans=1;
for(int i=0;i<cnt;i++)
{
if(prime[i]>n)break;
ll sum=0,x=n;
while(x)
{
sum+=x/prime[i];
x/=prime[i];
}
//cout<<sum<<endl;
ll xx=((sum+1)+(sum*(sum+1)/2))%M;
ans=ans*xx%M;
}
printf("%lld\n",ans);
}
system("pause");
return 0;
}