日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

a^b%c 的三种形式

發(fā)布時(shí)間:2024/5/24 综合教程 25 生活家
生活随笔 收集整理的這篇文章主要介紹了 a^b%c 的三种形式 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

求a^b%c,(1 <= a,b <= 2^62, 1 <= c <= 10^9)

最主要的高速冪

_LL mod_exp(_LL a, _LL b, int c)
{
    _LL ans = 1;
    _LL t = a%c;

    while(b)
    {
        if(b&1)
            ans = ans*t%c;
        t = t*t%c;
        b >>= 1;
    }
    return ans;
}



求a^b%c,(1 <= a,b,c <= 2^62)

由于c在long long范圍內(nèi),中間兩個(gè)long long 相乘的時(shí)候會(huì)超long long。所以對(duì)乘法再寫一個(gè)高速乘法的函數(shù),將乘法變?yōu)榧臃ǎ考右淮尉瓦M(jìn)行取模,就不會(huì)超long long了。

#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
#define LL long long
#define _LL __int64
#define eps 1e-12
#define PI acos(-1.0)
#define C 240
#define S 20
using namespace std;
const int maxn = 110;

// a*b%c
LL mul_mod(LL a, LL b, LL c)
{
	LL ans = 0;
	a %= n;
	b %= n;
	while(b)
	{
		if(b&1)
		{
			ans = ans+a;
			if(ans >= c) ans -= c;
		}
		a <<= 1;
		if(a >= c)
			a -= c;
		b >>= 1;
	}
	return ans;
}
//a^b%c
LL pow_mod(LL a, LL b, LL c)
{
	LL ans = 1;
	a = a%c;
	while(b)
	{
		if(b&1)
			ans = mul_mod(ans,a,c);
		a = mul_mod(a,a,c);
		b >>= 1;
	}
	return ans;
}
int main()
{
	LL a,b,c;
	while(~scanf("%lld %lld %lld",&a,&b,&c))
	{
		LL ans = pow_mod(a,b,c);
		printf("%lld
",ans);
	}
	return 0;
}

求a^b%c (1 <= a,c <= 10^9, 1 <= b <= 10^1000000)

b相當(dāng)大,高速冪超時(shí)。

有一個(gè)定理: a^b%c = a^(b%phi[c]+phi[c])%c,當(dāng)中要滿足b >= phi[c]。這樣將b變?yōu)閘ong long范圍內(nèi)的數(shù),再進(jìn)行高速冪。至于這個(gè)定理為什么成立,如今明確一點(diǎn)。這篇講的挺具體:http://www.narutoacm.com/archives/a-pow-b-mod-m/

http://acm.fzu.edu.cn/problem.php?pid=1759

#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
#define LL long long
#define _LL __int64
#define eps 1e-12
#define PI acos(-1.0)
#define C 240
#define S 20
using namespace std;
const int maxn = 110;

LL a,c,cc;
char b[1000010];

LL Eular(LL num)
{
	LL res = num;
	for(int i = 2; i*i <= num; i++)
	{
		if(num%i == 0)
		{
			res -= res/i;
			while(num%i == 0)
				num /= i;
		}
	}
	if(num > 1)
		res -= res/num;
	return res;
}

bool Comper(char s[], LL num)
{
	char bit[30];
	int len2 = 0,len1;
	while(num)
	{
		bit[len2++] = num%10;
		num = num/10;
	}
	bit[len2] = '';

	len1 = strlen(s);
	if(len1 > len2)
		return true;
	else if(len1 < len2)
		return false;
	else
	{
		for(int i = 0; i < len1; i++)
		{
			if(s[i] < bit[len1-i-1])
				return false;
		}
		return true;
	}
}

//對(duì)大整數(shù)取模,一位一位的取。
LL Mod(char s[], LL num)
{
	int len = strlen(s);
	LL ans = 0;
	for(int i = 0; i < len; i++)
	{
		ans = (ans*10 + s[i]-'0')%num;
	}
	return ans;
}

LL Pow(LL a, LL b, LL c)
{
	LL ans = 1;
	a = a%c;
	while(b)
	{
		if(b&1)
			ans = ans*a%c;
		a = a*a%c;
		b >>= 1;
	}
	return ans;
}

int main()
{
	while(~scanf("%lld %s %lld",&a,b,&c))
	{
		LL phi_c = Eular(c);
		LL ans;
		if(Comper(b,phi_c)) // b >= phi[c]
		{
			cc = Mod(b,phi_c)+phi_c;
			ans = Pow(a,cc,c);
		}
		else
		{
			int len = strlen(b);
			cc = 0;
			for(int i = 0; i < len; i++)
				cc = cc*10 + b[i]-'0';
			ans = Pow(a,cc,c);
		}
		printf("%lld
",ans);
	}
	return 0;
}

總結(jié)

以上是生活随笔為你收集整理的a^b%c 的三种形式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。