【题解】AcWing 89.a^b 与 90.64位整数乘法

AcWing 89.a^b

题目描述

a a a b b b 次方对 p p p 取模的值。

输入格式

三个整数 a , b , p a,b,p a,b,p,在同一行用空格隔开。

输出格式

输出一个整数,表示 a^b mod p的值。

数据范围

0 ≤ a , b ≤ 1 0 9 0≤a,b≤10^9 0a,b109
1 ≤ p ≤ 1 0 9 1≤p≤10^9 1p109

输入样例

3 2 7

输出样例

2

题目分析

快速幂。根据二进制, 如 b b b 在二进制表示下有 k k k 位,其中第 i ( 0 ≤ i ≤ k ) i (0\le i \le k) i(0ik) 位的数字是 c i c_i ci,那么 b = c k − 1 2 k − 1 + c k − 1 2 k − 2 + … + c 0 2 0 b=c_{k-1}2^{k-1}+c_{k-1}2^{k-2}+… +c_02^0 b=ck12k1+ck12k2++c020。因此, a b = a c k − 1 2 k − 1 ∗ a c k − 1 2 k − 2 ∗ … ∗ a c 0 2 0 a^b=a^{c_{k-1}2^{k-1}}*a^{c_{k-1}2^{k-2}}*… *a^{c_02^0} ab=ack12k1ack12k2ac020。又 a 2 i = ( a 2 i − 1 ) 2 a^{2^i}=(a^{2^{i-1}})^2 a2i=(a2i1)2,因此我们可以通过 k k k 次递推求出每个乘积项,当 c i = 1 c_i=1 ci=1 时将这一项乘入结果中,时间复杂度 O ( k ) = O ( l o g b ) O(k)=O(logb) O(k)=O(logb)

代码:

int power(int a, int b, int p){
    
    
	if (p == 1) return 0;  //特判
	int res = 1;
	while (b){
    
    
		if (b & 1) res = res * a % p;
		a = a * a % p;
		b >>= 1;
	}
	return res;
}

AcWing 90. 64位整数乘法

题目描述

a a a b b b p p p 取模的值。

输入格式

第一行输入整数 a a a,第二行输入整数 b b b,第三行输入整数 p p p

输出格式

输出一个整数,表示 a*b mod p的值。

数据范围

1 ≤ a , b , p ≤ 1 0 18 1≤a,b,p≤10^{18} 1a,b,p1018

输入样例

3
4
5

输出样例:

2

题目分析

龟速乘。与上题快速幂的思想类似, a ∗ b = a ∗ c k − 1 ∗ 2 k − 1 + a ∗ c k − 2 ∗ 2 k − 2 + … + a ∗ c 0 ∗ 2 0 a*b=a*c_{k-1}*2^{k-1}+a*c_{k-2}*2^{k-2}+…+a*c_0*2^0 ab=ack12k1+ack22k2++ac020 k k k 次递推求出每个成积项,如果 c i = 1 c_i=1 ci=1 就将其加入结果中,时间复杂度 O ( l o g b ) O(logb) O(logb)。该方法可以保证运算过程中long long不会溢出。

代码:

long long mul(long long a, long long b, long long p){
    
    
	long long res = 0;
	while (b){
    
    
		if (b & 1) res = (res + a) % p;
		a = a * 2 % p;
		b >>= 1;
	}
	return res;
}

猜你喜欢

转载自blog.csdn.net/f4u4u4r/article/details/117934567