zoukankan      html  css  js  c++  java
  • 快速幂、快速乘

    快速幂等算法都是基于二进制优化的算法,本文不做过多叙述,在此只是留下模板,并介绍(O(1))快速乘

    快速幂

    int qpow(int a, int b, int p) {
    	int res = 1 % p;
    	for (; b; b >>= 1, a = (long long) a * a % p) if (b & 1)
    		res = (long long) res * a % p;
    	return res;
    }
    

    快速乘

    #define qword long long
    qword qmul(qword a, qword b, qword p) {
    	qword res = 0;
    	for (; b; b >>= 1, a = (a + a) % p) if (b & 1)
    		res = (res + a) % p;
    	return res;
    }
    

    (O(1)) 快速乘

    利用 (a * b pmod p = a * b - [a * b / p] * p)
    首先 $ a,b < p $ 时, $ a * b / p $ 一定小于 $ p $ ,我们可以用浮点数进行 $ a * b / p $ 的运算,而不用关心小数点后面的部分。浮点类型long double在十进制下可以储存 $ 18~19 $ 位。
    当浮点数的精度不足以保证位数时,它会以科学记数法舍弃低位,这并不会影响我们需要的整数部分的运算
    另外,虽然 $ a * b $ 和 $ a * b / p $ 可能很大,但是二者的差一定在 $ 0 ~ p-1 $ 之间,我们只关心它们的较低位数就可以,所以,我们用long long储存 $a * b $ 和 $ [a * b / p] * p $ 各自的结果,整数溢出相当于舍弃最高位,也正好符合我们的要求

    #define qword long long
    qword mul(qword a, qword b, qword p) {
    	a %= p, b %= p;
    	qword c = (long double) a * b / p;
    	qword ans = a * b - c * p;
    	if (ans < 0) ans += p;
    	else if (ans >= p) ans -= p;
    	return ans;
    }
    
  • 相关阅读:
    UVALive 6044(双连通分量的应用)
    hdu 3760(2次bfs求最短路)
    zoj 3370(二分+二分图染色)
    sgu 326(经典网络流构图)
    hdu 4291(矩阵+暴力求循环节)
    uva 11381(神奇的构图、最小费用最大流)
    hdu 4685(匹配+强连通分量)
    hdu 4496(并查集)
    hdu 4722(记忆化搜索)
    Linux安装Nginx使用负载均衡
  • 原文地址:https://www.cnblogs.com/Alessandro/p/9709264.html
Copyright © 2011-2022 走看看