次方求模
时间限制:1000 ms | 内存限制:65535 KB
难度:3
描述
-
求a的b次方对c取余的值
输入
-
第一行输入一个整数n表示测试数据的组数(n<100)
每组测试只有一行,其中有三个正整数a,b,c(1=<a,b,c<=1000000000)
输出
-
输出a的b次方对c取余之后的结果
样例输入
-
3
2 3 5
3 100 10
11 12345 12345
样例输出
-
3
1
10481
#include<stdio.h>
int main(){
int n;
long long a, b, c;
long long ans;
scanf("%d",&n);
while(n--){
ans = 1;
scanf("%lld%lld%lld", &a, &b, &c);
while(b){
if(b & 1)
ans =(ans * a) % c;
a =(a * a) % c;
b >>= 1;
}
printf("%lld\n", ans);
}
return 0;
}
乘法取模:xy mod n = (x mod n)(y mod n)mod n
次方求模
时间限制:1000 ms | 内存限制:65535 KB
难度:3
求a的b次方对c取余的值
-
输入
-
第一行输入一个整数n表示测试数据的组数(n<100)
每组测试只有一行,其中有三个正整数a,b,c(1=<a,b,c<=1000000000)
输出
- 输出a的b次方对c取余之后的结果 样例输入
-
3 2 3 5 3 100 10 11 12345 12345
样例输出
-
3 1 10481
#include<stdio.h>
int main(){
int n;
long long a, b, c;
long long ans;
scanf("%d",&n);
while(n--){
ans = 1;
scanf("%lld%lld%lld", &a, &b, &c);
while(b){
if(b & 1)
ans =(ans * a) % c;
a =(a * a) % c;
b >>= 1;
}
printf("%lld\n", ans);
}
return 0;
}
加法取模: (x + y)mod n = ((x mod n) + (y mod n)) mod n
详见挑战编程 128页
【转】快速求幂:
2原理
把b转换成二进制数。
该二进制数第i位的权为
例如
11的二进制是1011
11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1
因此,我们将a¹¹转化为算
3实现
快速幂可以用位运算这个强大的工具实现
1
|
b and 1 {也就是取b的二进制最末位}
|
1
|
b shr 1 {就是去掉b的二进制最末位}
|
有了这个强大的工具,快速幂就好实现了!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
var a,b,n: int64 ;
function f(a,b,n: int64 ): int64 ;
var t,y: int64 ;
begin
t:= 1 ;y:=a;
while b<> 0 do
begin
if (b and 1 )= 1 then t:=t*y mod n;
y:=y*y mod n;
{
这里用了一个很强大的技巧,y*y即求出了
a^(2^(i-1))
不知道这是什么的看原理
}
b:=b shr 1 ; {去掉已经处理过的一位}
end ;
exit(t);
end ;
begin
read(a,b,n); {n是模}
writeln (f(a,b,n));
end .
|
4代码比较
常规求幂
1
2
3
4
5
6
7
|
int pow1( int a, int b )
{
int r = 1;
while ( b-- )
r *= a;
return r;
}
|
二分求幂(一般)
1
2
3
4
5
6
7
8
9
10
11
12
|
int pow2( int a, int b )
{
int r = 1, base = a;
while ( b != 0 )
{
if ( b % 2 )
r *= base;
base *= base;
b /= 2;
}
return r;
}
|
快速求幂(位操作)
1
2
3
4
5
6
7
8
9
10
11
12
|
int pow3( int a, int b )
{
int r = 1, base = a;
while ( b != 0 )
{
if ( b & 1 )
r *= base;
base *= base;
b >>= 1;
}
return r;
}
|
快速求幂(更高效率的位运算法)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
int pow4( int x, int n)
{
int result;
if (n == 0)
return 1;
else
{
while ((n & 1) == 0)
{
n >>= 1;
x *= x;
}
}
result = x;
n >>= 1;
while (n != 0)
{
x *= x;
if ((n & 1) != 0)
result *= x;
n >>= 1;
}
return result;
}
|