AcWing90. 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} 1≤a,b,p≤1018

输入样例

复制代码
3
4
5

输出样例

复制代码
2

思路

C++ 内置的最高整数类型是 64 位,现在 a ∗ b a * b a∗b mod p p p 中的三个变量 a , b , p a, b, p a,b,p 都在 1 0 18 10^{18} 1018 级别,则不存在一个可供强制转换的 128 位整数类型,需要一些特殊的处理办法。

类似快速幂 的思想,把整数 b b b 用二进制表示,即 b = c k − 1 2 k − 1 + c k − 2 2 k − 2 + . . . + c 0 2 0 b = c_{k-1}2^{k-1} + c_{k-2}2^{k-2} + ... + c_02^0 b=ck−12k−1+ck−22k−2+...+c020,则 a ∗ b = c k − 1 ∗ a ∗ 2 k − 1 + c k − 2 ∗ a ∗ 2 k − 2 + . . . + c 0 ∗ a ∗ 2 0 a * b = c_{k-1} * a * 2^{k-1} + c_{k-2} * a * 2^{k-2} + ... + c_{0} * a * 2^{0} a∗b=ck−1∗a∗2k−1+ck−2∗a∗2k−2+...+c0∗a∗20。

因为 a ∗ 2 i = ( a ∗ 2 i − 1 ) ∗ 2 a * 2^{i} = (a * 2 ^{i-1}) * 2 a∗2i=(a∗2i−1)∗2,若已求出 a ∗ 2 i − 1 a * 2^{i-1} a∗2i−1 mod p p p,则计算 ( a ∗ 2 i − 1 ) ∗ 2 (a * 2 ^{i-1}) *2 (a∗2i−1)∗2 mod p p p 时,运算过程中每一步的结果都不超过 2 ∗ 1 0 18 2 * 10^{18} 2∗1018,仍然在 64 位整数 long long 的表示范围内,所以很容易通过 k k k 次递推求出每个乘积项。当 c i = 1 c_i = 1 ci=1 时,把该乘积项累加到答案中即可。

时间复杂度为 O ( l o g 2 b ) O(log_2b) O(log2b)。

代码

cpp 复制代码
#include <cstdio>

using namespace std;

typedef long long ll;

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

int main() {
    ll a, b, p;
    scanf("%lld%ld%lld", &a, &b, &p);
    printf("%lld\n", mul(a, b, p));
    return 0;
}
相关推荐
汀、人工智能3 天前
03 - 运算符
数据结构·算法·数据库架构·位运算·哈希表·03 - 运算符
We་ct3 天前
LeetCode 137. 只出现一次的数字 II:从基础到最优的两种解法详解
前端·数据结构·算法·leetcode·typescript·位运算
汉克老师4 天前
GESP2024年12月认证C++三级( 第一部分选择题(9-15))
c++·字符串·位运算·进制·补码·gesp三级·gesp3级
We་ct4 天前
LeetCode 136. 只出现一次的数字:线性时间+常量空间最优解拆解
前端·算法·leetcode·typescript·位运算
汉克老师8 天前
GESP2025年6月认证C++三级( 第一部分选择题(9-15))
c++·字符串·位运算·gesp三级·gesp3级
旖-旎10 天前
位运算(只出现一次的数字|||)(5)
c++·算法·leetcode·位运算
旖-旎11 天前
位运算(两整数之和)(3)
c++·算法·leetcode·位运算
旖-旎12 天前
位运算(判断字符是否唯一)(1)
c++·算法·leetcode·位运算
俩娃妈教编程1 个月前
C++基础知识点:位运算
java·开发语言·jvm·c++·位运算
问好眼1 个月前
《算法竞赛进阶指南》0x01 位运算-3.64位整数乘法
c++·算法·位运算·信息学奥赛