这是我参与「第四届青训营 」笔记创作活动的第1天
刚接触算法 放一个快速幂模板 基于位运算的思想
题目大意
求 a 的 b 次方对 p 取模的值。
输入格式
三个整数 a,b,p ,在同一行用空格隔开。 输出格式
输出一个整数,表示
a^b mod p的值。 数据范围 0≤a,b≤109 \ 1≤p≤109输入样例:
3 2 7输出样例:
2
ACcode
// Problem: a^b
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/91/
// Memory Limit: 32 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <sstream>
#include <vector>
#define endl '\n'
#define ios \
ios::sync_with_stdio(0); \
cin.tie(0); \
cout.tie(0);
#define DEBUG printf("Passing [%s] in LINE %d\n", __FUNCTION__, __LINE__)
//
using namespace std;
const int N = 2e5 + 10;
const int minN = 1e3 + 10;
int n, m, t;
// char cha1[minN], cha2[minN];
// string s, str1[N], str2[N];
\
// int a[N], b[N];
int tot, le[1], rt[1], key[1], value[1];
\
void debug() // splay
{
int i;
for (i = 0; i <= tot; i++)
printf("Node[%d] le=%d rt=%d key=%d value=%d\n", i, le[i], rt[i], key[i],
value[i]);
}
\
bool cmp(int a, int b) { return a > b; }
\
void solve() {
// 快速幂
int a, b, p;
cin >> a >> b >> p;
int res = 1 % p;
while (b) {
if (b & 1) res = res * 1ll * a % p;
a = a * 1ll * a % p; // 处理b的下一位
b >>= 1; // 上面已经处理了个位,把个位去掉
}
cout << res;
}
\
signed main() {
// int n, k;
// scanf("%d %d", &n, &k);
// for(int i = 1;i <= n; ++i) cin >> a[i];
solve();
return 0 ^ 0;
}
以及分享一个讲二分答案 讲的很清晰的一个帖子
~ 建议那天的 [跟着月影学js] 改名为 [跟着月影学算法]
一个 acwing 上的 推公式步骤
因为 pow 函数得到的值是 double 类型,有效数字只有 15∼16 位,并不能求出精确值。这道题目是让我们求出精确值对某个数的余数,所以这道题我们可以使用快速幂来做。 如果 b在二进制下有 k 位,其中第 i(0≤i≤k)位的数字是 ci,有: b=ck−1 2 k−1+ck−2 2 k−2+⋅⋅⋅+c0 2 0
于是:
ab=ack−1 2 k−1 ∗ ack−2 2 k−2 ∗ ⋅⋅⋅ ∗ ac0 2 0
又因为:
a2i=(a2i−1)2 所以我们可以通过上一次计算的结果来计算下一次计算的结果。这公式这么复杂,到底怎么理解呢?手动模拟一下就可以啦!