快速幂+龟速乘

快速幂+龟速乘

今天在牛客遇到一道题华华教月月做数学
我看了一下题,发现是让求a^b%p,我一看就知道应该是快速幂,就非常高兴的开始写起来,但是写完的时候,发现连给的第二个样例都过不去,才发现,原来爆long long 了。
我看了一下题解,又搜了一下网上的资料,发现快速幂的弊端就是容易爆longlong,所以还有一种可以解决爆longlong的方法,那就是龟速乘,所以就去学了一下,然后AC了。
借鉴的大佬博客
快速幂模板

ll quick_pow(ll a,ll b, ll p)
{
	ll res=1;
	while(b)
	{
		if(b&1) res=low_times(res,a,p);
		a=low_times(a,a,p);
		b>>=1;
	}
	return res;
}

龟速乘模板

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

我的AC代码

#include
#include
typedef long long ll;
using namespace std;
ll low_times(ll a,ll b,ll p)
{
	ll res=0;
	while(b)
	{
		if(b&1) res=(res+a)%p;
		a=(a<<1)%p;
		b>>=1;
	}
	return res;
}
ll quick_pow(ll a,ll b, ll p)
{
	ll res=1;
	while(b)
	{
		if(b&1) res=low_times(res,a,p);
		a=low_times(a,a,p);
		b>>=1;
	}
	return res;
}
ll a,b,p;
int main()
{
	int n;
	cin>>n;
	while(n--)
	{
		cin>>a>>b>>p;
		cout<<quick_pow(a,b,p)<<endl;
	}
	return 0;
}

二进制真的神奇。
a>>=1 向右进一位。
例如 14的二进制 1110;
向右进一位 111;

你可能感兴趣的:(快速幂+龟速乘)