a^b_牛客网

链接: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
}

做个笔记,如有错误欢迎大家指正!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值