其他分享
首页 > 其他分享> > 数学技巧

数学技巧

作者:互联网

数学技巧

题目

题目

快速幂

求 \(a^b\) .  由于 \(b=c_{k-1}2^{k-1} + c_{k-2}2^{k-2}+...+c_02^0\), 其中 \(k=\lceil log(b+1)\rceil\)​(b在二进制下的位数)

我们可以递推.

int qpow(int a, int b){
    a%=MOD;							// 别漏了~
	int res=1;
	while(b){
		if(b&1) res=(res*a)%MOD;	// 若MOD略大, 这里可能需要转 long long
		a=(a*a)%MOD; b>>=1;
	}
	return res;
}

速乘

由于乘法可能会爆 long long, 比如 快速幂中的乘法, 如果 MOD很大(比如为INT_MAX) 就很有可能爆long long.
写 高精度? 太麻烦了, 不仅容易出错, 还效率很低.   
于是有了如下两个速乘: 龟速乘和快速乘

龟速乘 \(O(log\ b)\)

与快速幂原理大同小异.

ll smul(ll a, ll b, ll P){
    ll res=0;
    while(b){	
		if(b&1) res=(res+a)%P;
        a=(a+a)%P; b>>=1;
    }
    return res;
}

快速乘 \(O(1)\)

核心为: \(ab\bmod p = ab-\lfloor ab/p\rfloor p\)​  记 \(c=\lfloor ab/p\rfloor\)​

ull qmul(ull a, ull b, ull p){
	a%=p, b%=p;
    ull c=(long double) a*b/p
    ull x=a*b, y=c*p;
    ll res=(ll)(x%p) - (ll)(y%p);	//这里的括号不要漏掉了
    if(res<0) res+=p;				//不要漏掉了.
    return res;
}

标签:ab,技巧,res,ll,long,数学,ull,MOD
来源: https://www.cnblogs.com/OldPanWeb/p/15919093.html