有多组测试数据。
每组给定
N
,
K
\small\rm N,K
N,K,令
S
\small\rm S
S为
200
8
N
\small\rm{2008^N}
2008N的正因数和
σ
(
200
8
N
)
\small\rm{\sigma(2008^N)}
σ(2008N),
M
≡
S
(
m
o
d
K
)
\small\rm{M\equiv S\pmod{K}}
M≡S(modK)。
求
200
8
M
(
m
o
d
K
)
\small\rm{2008^M\pmod{K}}
2008M(modK)。
1 ≤ N ≤ 1 0 7 \small\rm1\le N\le 10^7 1≤N≤107, 500 ≤ K ≤ 1 0 4 \small\rm500\le K\le 10^4 500≤K≤104。
要求的是
[
200
8
σ
(
200
8
N
)
%
K
]
%
K
{\left[2008^{\sigma(2008^N)\%K}\right]\%K}
[2008σ(2008N)%K]%K。我们先设
k
=
ω
(
200
8
N
)
\small k=\omega(2008^N)
k=ω(2008N)。
数据范围很大,所以暴力应该是不行的,首先得对公式做一些简化。
提起因数,我就想到唯一分解定理
(1)
200
8
N
=
∏
i
=
1
k
p
i
a
i
{2008^N=\prod\limits_{i=1}^{k}p_i^{a_i}}\tag{1}
2008N=i=1∏kpiai(1)
那么,
σ
(
200
8
N
)
\small\sigma(2008^N)
σ(2008N)呢?
(2)
σ
(
200
8
N
)
=
∏
i
=
1
k
∑
j
=
1
a
i
p
i
j
\sigma(2008^N)=\prod\limits_{i=1}^k\sum\limits_{j=1}^{a_i}p_i^j\tag{2}
σ(2008N)=i=1∏kj=1∑aipij(2)
我们知道等比数列求和公式
(3)
∑
i
=
1
n
a
1
q
i
−
1
=
a
1
⋅
1
−
q
n
1
−
q
\sum\limits_{i=1}^na_1q^{i-1}=a_1\cdot\frac{1-q^n}{1-q}\tag{3}
i=1∑na1qi−1=a1⋅1−q1−qn(3)
由
(
2
)
\small(2)
(2)、
(
3
)
\small(3)
(3),得到:
(4)
σ
(
200
8
N
)
=
∏
i
=
1
k
p
i
⋅
1
−
p
i
a
i
1
−
p
i
\sigma(2008^N)=\prod\limits_{i=1}^kp_i\cdot\frac{1-p_i^{a_i}}{1-p_i}\tag{4}
σ(2008N)=i=1∏kpi⋅1−pi1−piai(4)
记
x
\small x
x对模
K
\small K
K的逆元为
x
−
1
\small x^{-1}
x−1。那么:
(5)
σ
(
200
8
N
)
≡
∏
i
=
1
k
p
i
(
1
−
p
i
a
i
)
(
1
−
p
i
)
−
1
(
m
o
d
K
)
\sigma(2008^N)\equiv\prod\limits_{i=1}^k p_i(1-p_i^{a_i})(1-p_i)^{-1}\pmod{K}\tag{5}
σ(2008N)≡i=1∏kpi(1−piai)(1−pi)−1(modK)(5)
这是一种处理除法取模的方法。但是逆元有一个条件!要求逆元的那个应该和
K
K
K互质!!
那我们就要思考一下除法取模还有什么办法了。
首先,很显然
(
1
−
p
i
)
∣
(
1
−
p
i
a
i
)
(1-p_i)|(1-p_i^{a_i})
(1−pi)∣(1−piai),那么,设
η
=
σ
(
200
8
N
)
m
o
d
  
K
\eta=\sigma(2008^N)\mod{K}
η=σ(2008N)modK:
(6)
η
=
{
∏
i
=
1
k
(
p
i
m
o
d
  
K
)
⋅
(
1
−
p
i
a
i
)
m
o
d
  
[
(
1
−
p
i
)
⋅
K
]
(
1
−
p
i
)
m
o
d
  
K
}
m
o
d
  
K
\eta=\left\{\prod\limits_{i=1}^k(p_i\mod{K})\cdot\frac{(1-p_i^{a_i})\mod{[(1-p_i)\cdot K]}}{(1-p_i)}\mod{K}\right\}\mod{K}\tag{6}
η={i=1∏k(pimodK)⋅(1−pi)(1−piai)mod[(1−pi)⋅K]modK}modK(6)
这个应该还是蛮容易推的?
(推
∀
a
,
b
∈
N
∗
\mathbf\forall a,b\in\N^*
∀a,b∈N∗,
a
∣
b
a|b
a∣b时
a
b
m
o
d
  
c
=
a
m
o
d
  
b
c
b
m
o
d
  
c
\dfrac{a}{b}\mod{c}=\dfrac{a\mod{bc}}{b}\mod{c}
bamodc=bamodbcmodc就可以了。也挺显然的。)
(当然你也可以上下分解质因数,不过我觉得挺麻烦的,万一爆常数了呢。)
现在,我们只需要利用
(
6
)
\small(6)
(6)求出
η
\small \eta
η。
但是怎么对 200 8 N \small 2008^N 2008N分解质因数?——设 2008 = ∏ i = 1 m p i t i \small2008=\prod\limits_{i=1}^mp_i^{t_i} 2008=i=1∏mpiti,
(7) 200 8 N = ∏ i = 1 m p i t i N 2008^N=\prod\limits_{i=1}^mp_i^{t_iN}\tag{7} 2008N=i=1∏mpitiN(7)
利用 ( 7 ) \small(7) (7),又因为对 2008 \small2008 2008做质因数分解不难,我们可以先唯一分解 2008 \small2008 2008。
(8) 2008 = 251 ∗ 2 3 2008=251*2^3\tag{8} 2008=251∗23(8)
考虑到并不用真的计算出 200 8 N \small2008^N 2008N:我们只需要分别记录 p i \small p_i pi和 t i N \small t_iN tiN就可以了。
(9) 200 8 N = 2 3 N 50 1 N \small2008^N=2^{3N}501^N\tag{9} 2008N=23N501N(9)
然后求
200
8
η
(
m
o
d
K
)
\small2008^{\eta}\pmod{K}
2008η(modK)。
这样就可以解决这道题目了。
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<algorithm>
using namespace std;
long long defpowm(long long a, long long b, long long m) {
long long ans = 1;
while(b) {
if (b&1) {
ans*=a;
ans%=m;
}
a*=a;
a%=m;
b>>=1;
}
return ans;
}
int main() {
long long n, k;
while(~scanf("%lld%lld", &n, &k)) {
if (n==0&&k==0) break;
long long temp0 = k*250ll;
long long temp1 = defpowm(251, n+1, temp0) - 1;
long long temp2 = defpowm(2, 3*n+1, temp0) - 1;
long long ans = temp1*temp2/250; ans %= k;
printf("%lld\n", defpowm(2008, ans, k));
}
return 0;
}