Description
A r i a Aria Aria正面临算设课程的考试。
设 F ( n ) = ∏ i = 1 n i ! F(n)=\prod\limits_{i=1}^ni! F(n)=i=1∏ni!
对于给定的 n , m n,m n,m(其中 n n n为质数),求 F ( n m ) F(n^m) F(nm)中质因子 n n n的出现次数,即求一个最大的非负整数 e e e满足 n e n^e ne整除 F ( n m ) F(n^m) F(nm)。
由于是算设课的考试,答案当然是对 1 0 9 + 7 10^9+7 109+7取模的。
Input
一行,两个正整数 n , m n,m n,m,其中 n n n是质数
( n , m ≤ 1 0 9 ) (n,m\le 10^9) (n,m≤109)
Output
一行,一个整数,质因子 n n n的出现次数,答案对 1 0 9 + 7 10^9+ 7 109+7取模。
Sample Input
233 2333
Sample Output
861127073
Solution
记所给素数为 p p p, S ( n ) S(n) S(n)表示 n ! n! n!中素数 p p p的幂指数,那么有 S ( n ) = ⌊ n p ⌋ + S ( ⌊ n p ⌋ ) S(n)=\lfloor\frac{n}{p}\rfloor+S(\lfloor\frac{n}{p}\rfloor) S(n)=⌊pn⌋+S(⌊pn⌋)
考虑
F
(
m
)
=
∑
i
=
0
p
m
−
1
S
(
i
)
F(m)=\sum\limits_{i=0}^{p^m-1}S(i)
F(m)=i=0∑pm−1S(i),答案即为
F
(
m
)
+
S
(
p
m
)
F(m)+S(p^m)
F(m)+S(pm),而
S
(
p
m
)
=
p
m
−
1
+
.
.
.
+
1
=
p
m
−
1
p
−
1
S(p^m)=p^{m-1}+...+1=\frac{p^m-1}{p-1}
S(pm)=pm−1+...+1=p−1pm−1
F
(
m
)
=
∑
i
=
0
p
m
−
1
(
⌊
i
p
⌋
+
S
(
⌊
i
p
⌋
)
)
=
p
⋅
∑
i
=
0
p
m
−
1
−
1
S
(
i
)
+
G
(
m
)
F(m)=\sum\limits_{i=0}^{p^m-1}(\lfloor\frac{i}{p}\rfloor+S(\lfloor\frac{i}{p}\rfloor)) =p\cdot \sum\limits_{i=0}^{p^{m-1}-1}S(i)+G(m)
F(m)=i=0∑pm−1(⌊pi⌋+S(⌊pi⌋))=p⋅i=0∑pm−1−1S(i)+G(m)
其中
G
(
m
)
=
∑
i
=
0
p
m
−
1
⌊
i
p
⌋
=
∑
i
=
1
p
m
−
1
−
1
p
⋅
i
=
p
m
(
p
m
−
1
−
1
)
2
G(m)=\sum\limits_{i=0}^{p^m-1}\lfloor\frac{i}{p}\rfloor =\sum\limits_{i=1}^{p^{m-1}-1}p\cdot i =\frac{p^m(p^{m-1}-1)}{2}
G(m)=i=0∑pm−1⌊pi⌋=i=1∑pm−1−1p⋅i=2pm(pm−1−1)
故有
F
(
m
)
=
p
⋅
F
(
m
−
1
)
+
p
m
(
p
m
−
1
−
1
)
2
=
p
⋅
F
(
m
−
1
)
+
1
2
⋅
p
m
+
1
2
⋅
p
2
m
−
1
F(m)=p\cdot F(m-1)+\frac{p^m(p^{m-1}-1)}{2}=p\cdot F(m-1)+\frac{1}{2}\cdot p^{m}+\frac{1}{2}\cdot p^{2m-1}
F(m)=p⋅F(m−1)+2pm(pm−1−1)=p⋅F(m−1)+21⋅pm+21⋅p2m−1,用矩阵快速幂维护
F
(
m
)
,
p
m
,
p
2
m
−
1
F(m),p^m,p^{2m-1}
F(m),pm,p2m−1的值即可,时间复杂度
O
(
l
o
g
m
)
O(logm)
O(logm)
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=100001;
#define mod 1000000007
int add(int x,int y)
{
x+=y;
if(x>=mod)x-=mod;
return x;
}
int mul(int x,int y)
{
ll z=1ll*x*y;
return z-z/mod*mod;
}
int Pow(int x,int y)
{
ll z=1;
while(y)
{
if(y&1)z=mul(z,x);
x=mul(x,x);
y>>=1;
}
return z;
}
typedef int M[3][3];
void MUL(M &A,M B)
{
M C;
memset(C,0,sizeof(C));
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
C[i][j]=add(C[i][j],mul(A[i][k],B[k][j]));
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
A[i][j]=C[i][j];
}
void POW(M &A,int n)
{
M B;
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
B[i][j]=(i==j);
while(n)
{
if(n&1)MUL(B,A);
MUL(A,A);
n>>=1;
}
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
A[i][j]=B[i][j];
}
int main()
{
int p,m;
M A;
while(~scanf("%d%d",&p,&m))
{
A[0][0]=p,A[0][1]=(mod+1)/2,A[0][2]=mod-(mod+1)/2;
A[1][0]=0,A[1][1]=mul(p,p),A[1][2]=0;
A[2][0]=0,A[2][1]=0,A[2][2]=p;
POW(A,m);
int ans=add(mul(A[0][1],p),mul(A[0][2],p));
ans=add(ans,mul(add(Pow(p,m),mod-1),Pow(p-1,mod-2)));
printf("%d\n",ans);
}
return 0;
}