题目
描述
给定n,m,k都是小于10001的正整数,输出给定的n个数中,其m次幂能被k整除的数的个数。输出满足条件的数的个数。
输入
两行组成,第一行是n,m,k。第二行是n个正整数,不超过10001.
输出
输出满足条件的数的个数。
样例输入
3 2 50
9 10 11
样例输出
1
法一(暴力)
暴力快速幂不说了
法二(指数)
指数循环节
a
m
%
k
=
a
m
%
φ
(
k
)
+
φ
(
k
)
%
k
a^m \%k=a^{m\%\varphi(k)+\varphi(k)}\%k
am%k=am%φ(k)+φ(k)%k
证明点这里绝对不是我不会证
#include <cstdio>
#include <iostream>
using namespace std;
int n, m, k, ans, u, ph_k;
inline int phi(int x){
int sum = x;
for(int i = 2; x != 1; i ++){
if( x%i == 0 ){
sum = sum/i*(i-1);
while( x%i == 0 )
x /= i;
}
}
return sum;
}
inline int qkp(int x, int y){
int sum = 1;
while( y ){
if( y&1 )
sum = sum*x%k;
x = x*x%k;
y >>= 1;
}
return sum;
}
int main(){
scanf("%d%d%d",&n,&m,&k);
ph_k = phi(k);
if( m > ph_k )
m = m%ph_k+ph_k;
for(int i = 1; i <= n; i ++){
scanf("%d", &u);
u %= k;
if( !qkp(u, m) )
ans ++;
}
printf("%d\n", ans);
return 0;
}
法三(分解)
整数的唯一分解
不知道的点这里
我们知道若
a
%
k
=
=
0
a\%k ==0
a%k==0
若
a
=
p
1
w
1
∗
p
2
w
2
∗
…
∗
p
o
w
o
a=p_1^{w_1}*p_2^{w_2}*…*p_o^{w_o}
a=p1w1∗p2w2∗…∗powo
若
k
=
p
1
g
1
∗
p
2
g
2
∗
…
∗
p
q
g
q
k=p_1^{g_1}*p_2^{g_2}*…*p_q^{g_q}
k=p1g1∗p2g2∗…∗pqgq
那么一定有
q
<
=
o
,
a
的
p
i
=
k
的
p
i
(
i
<
=
q
)
且
(
a
的
p
i
的
w
i
)
一
定
>
(
k
的
p
i
的
g
i
)
q<=o,a的p_i=k的p_i(i<=q)且(a的p_i的w_i)一定>(k的p_i的g_i)
q<=o,a的pi=k的pi(i<=q)且(a的pi的wi)一定>(k的pi的gi)
所以我们先把
a
a
a分解之后,再用上面的定理判断
a
b
和
k
a^b和k
ab和k即可
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int n, m, k, ans, u, cnt;
int p[14], w[14], wu[14];
inline int fen(int x){
memset(wu, 0, sizeof(wu));
for(int i = 1; i <= cnt; i ++){
while( x%p[i] == 0 ){
wu[i]++;
x/=p[i];
}
wu[i] *= m;
if( wu[i] < w[i] )
return 1;
}
return 0;
}
int main(){
scanf("%d%d%d",&n,&m,&k);
int x = k;
for(int i = 2; i <= k; i ++){
if( x%i == 0 ){
p[++cnt] = i;
while( x%i == 0 ){
x /= i;
w[cnt]++;
}
}
}
for(int i = 1; i <= n; i ++){
scanf("%d", &u);
if( fen(u) == 0 )
ans ++;
}
printf("%d\n", ans);
return 0;
}