大数乘法取模运算(二进制)

问题:

求 (a*b) % m 的值,其中 a,b,m 是1到10^18;

如果直接乘的话,因为a和b还有m都很大,那么会溢出long long,所以需要一些方法;

朴素的想法是用数组模拟高精度,但是比较麻烦;

二进制数也是满足十进制竖式乘法运算规律的,我们可以模拟二进制乘法竖式来计算(a*b)%m,因为其每次只相当于a乘2,再取模就不会溢出了;

代码:

#include <bits/stdc++.h>
#define MAXN 100000+10
#define ll long long
using namespace std;

ll multi(ll a, ll b, ll m)
{
    ll ans=0;
    while(b)
    {
        if(b&1) (ans+=a)%=m;
        (a<<=1)%=m;
        b>>=1;
    }
    return ans;
}

int main(void)
{
    std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    ll a, b, m;
    cin >> a >> b >> m;
    cout << multi(a, b, m) << endl;
    return 0;
}

困苦艰难,玉汝于成    ————         geloutingyu

时间: 2024-10-25 15:18:27

大数乘法取模运算(二进制)的相关文章

ACwing90 64位整数乘法 大数乘法取模

网址:https://www.acwing.com/problem/content/92/ 题解: 大数乘法取模模板. AC代码: #include <bits/stdc++.h> using namespace std; long long add(long long a, long long b, long long p) { long long res = 0; while (b) { if (b & 1) res = (res + a) % p; a = (a * 2) % p

Divide two numbers,两数相除求商,不能用乘法,除法,取模运算

问题描述:求商,不能用乘法,除法,取模运算. 算法思路:不能用除法,那只能用减法,但是用减法,超时.可以用位移运算,每次除数左移,相当于2倍. 1 public class DividTwoIntegers { 2 public int divide(int dividend, int divisor) 3 { 4 if(divisor == 0) return Integer.MAX_VALUE; 5 if(divisor == -1 && dividend == Integer.MIN

分数的乘法逆元和负数的取模运算

1.乘法逆元 A.定义 如果ax≡1 (mod p),且gcd(a,p)=1(a与p互质),则称a关于模p的乘法逆元为x. 既然有ax≡1 (mod p),那么有ax - py = 1,x是a关于模p的乘法逆元. B.分数的乘法逆元 对于实数域,一个数的乘法逆元就是其倒数,所谓乘法逆元就是相乘等于单位元的那个数. 对于ecc算法的离散曲线域,m的乘法逆元为n,满足m * n = 1 (mod p),即满足m*n mod p = 1 mod p,称作n就是m关于的p乘法逆元.在离散曲线域中,单位元

a ^ b mod c 取模运算优化反思(老物)

这是一篇嘲讽我之前的自己采用笨重愚蠢思想去解决问题的日志. RSA 加密与解密涉及到 a ^ b mod c 的问题,如何计算这个值呢? 我会选择 pow(a, b) % c, 事实上在写RSA的时候确实是这么干的,但现在看来真心愚蠢, 因为我为此不得不去实现了一个自己的大数四则运算库,也就是以数组为数(BigNum),而对于mod运算只需要换算为 A % B = A - ( A / B ) * B , 好吧,我自认为轮子准备充分了, 很快就写完了,也觉得很满意,也没什么不合适的地方,但现在开始

51NOD 1116 K进制下的大数(字符串取模 + 枚举)

传送门 1116 K进制下的大数 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 有一个字符串S,记录了一个大数,但不知这个大数是多少进制的,只知道这个数在K进制下是K - 1的倍数.现在由你来求出这个最小的进制K. 例如:给出的数是A1A,有A则最少也是11进制,然后发现A1A在22进制下等于4872,4872 mod 21 = 0,并且22是最小的,因此输出k = 22(大数的表示中A对应10,Z对应35). Input 输入大数对应的字符串S

快速乘法取模算法

原理: 32+16+4=52 1 LL qmul(LL x, LL y, LL mod) { // 乘法防止溢出, 如果p * p不爆LL的话可以直接乘: O(1)乘法或者转化成二进制加法 2 //快速乘法取模算法 3 4 LL ret = 0; 5 while(y) { 6 if(y & 1) 7 ret = (ret + x) % mod; 8 x = x * 2 % mod; 9 y >>= 1; 10 } 11 return ret; 12 } 原文地址:https://www

大整数取模运算出现运算结果负数的解决方案

首先我们看个例子 <?php echo 12121212121 % 1000000; //结果为 -689767 //实际应该为12121 ?> 这里的取模运算(取余数)出现了BUG.那么需要声明一下,负数也是可以取模操作的,并不是出现负数就是不对的我们应该把这种长整数类型看成float型数据进行处理介绍一个函数float fmod ( float $x , float $y )返回除法的浮点数余数通过这个函数的运算,就可以得到原本想要的余数结果 <?php $a = floatval(

HDU6128 二次剩余/二次域求二次剩余解/LL快速乘法取模

LINK 题意:求满足模p下$\frac{1}{a_i+a_j}\equiv\frac{1}{a_i}+\frac{1}{a_j}$的对数,其中$n,p(1\leq n\leq10^5,2\leq p\leq10^{18})$ 思路:推式子,两边同乘$(a_i + a_j)^3$,得$a_i^2+a_j^2 \equiv {a_i·a_j} \mod{p}$,进一步$a_i^2+a_j^2+a_i·a_j\equiv {0} \mod{p}$,然后?然后会点初中数竞,或者数感好会因式分解就能看出

poj 3980 取模运算

取模运算 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10931   Accepted: 6618 Description 编写一个C函数mod(int n, int m),实现取模运算% Input 输入包含多行数据 每行数据是两个整数a, b (1 <= a, b <= 32767) 数据以EOF结束 Output 于输入的每一行输出a%b Sample Input 5 3 100 2 Sample Output