AcWing 90. 64位整数乘法 龟速乘
题目链接:
正经题意:
求
a
∗
b
(
m
o
d
p
)
a * b \pmod p
a∗b(modp)的值。
1
<
=
a
,
b
,
p
<
=
1
0
18
1 <= a,b,p <= 10^{18}
1<=a,b,p<=1018
简而言之:
注意数据范围,这是longlong相乘都会爆掉的,所以要用到龟速乘
思路:
a
∗
b
=
a
b
1
⋅
2
0
+
a
b
2
⋅
2
1
+
⋯
+
a
b
n
⋅
2
n
−
1
a * b = a^{b_1} \cdot2^0 +a^{b_2} \cdot2^1 +\dots+a^{b_n} \cdot2^{n-1}
a∗b=ab1⋅20+ab2⋅21+⋯+abn⋅2n−1
该式意味着,b某一位二进制值为1则加
2
i
−
1
∗
a
2^{i-1}\ast a
2i−1∗a
所以我们可以通过遍历b的所有二进制位寻找答案
是不是很像快速幂的思想
注意:这里的bi是二进制下,该位置的二进制值
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL qadd(LL a,LL b,LL c){
LL res = 0;
while(b){
if(b&1) res = (res + a)%c;
a = (a + a) %c;
b >>= 1;
}
return res;
}
int main(){
LL a,b,c;
cin>>a>>b>>c;
LL s = qadd(a,b,c);
cout<<s;
}
/*
写一个快速幂作为对比
int qpow(int a,int b,int c){
int res = 1;
while(b){
if(b&1) res = res*a%c;
a = a * a % c;
b >>= 1;
}
return res;
}
*/