链接:https://ac.nowcoder.com/acm/contest/996/A
来源:牛客网
题目描述
求 a 的 b 次方对 p 取模的值,其中
0≤a,b,p≤109,p>0
输入描述:
三个用空格隔开的整数a,b和p。
输出描述:
一个整数,表示
ab mod p的值。
示例1
输入
2 3 9
输出
8
分析:
计算ab,如果把 b写成2进制,如13的二进制1101,于是3号位、2号位、0号位就都是1,那么就可以得到13 = 23 + 22 + 21 = 8 + 4 + 1。所以a13 = a8a4a1。
核心1:
把b转换成二进制,然后将b的二进制数从右到左判断,如果判断为1,则res乘上当前的次方
eg:35-> 3(101)–>res = 1(res的初始值) * a^( 2^0 ) (第一次操作) * a^( 2^2)(第二次操作)
核心2:
每次循环的时候不管要不要对res进行操作,都要对a进行一次操作,即a = a * a,假如到了第n次循环,此时正在判断b的二进制的第n-1位是否为1。又因为a在第一次进入循环时,为a^1 ,即a^( 2^0) ,那么第n次循环就是a^( 2n-1),正好b正在判断第n-1位,此时如果为1,则直接将res=res*a即可。
注:上面的数字前写“^”符号,或者数字位于右上角都表示次方,这块写的时候不太好表示。
package main
import (
"bufio"
"fmt"
"os"
)
var (
reader = bufio.NewReader(os.Stdin) // 快读
writer = bufio.NewWriter(os.Stdout) // 快读
)
func toBase(a, b, p int64) int64 {
var res int64 = 1
for b > 0 {
if b&1 == 1 {
res = res * a % p
}
a = a * a % p
b = b >> 1
}
return res%p
}
func main() {
defer writer.Flush()
var a, b, p int64
fmt.Fscan(reader, &a)
fmt.Fscan(reader, &b)
fmt.Fscan(reader, &p)
res := toBase(a, b, p)
fmt.Fprintln(writer, res)
return
}
做个笔记,如有错误欢迎大家指正!