a^b%c 的三种形式
来源:互联网 发布:大数据的定义及特点 编辑:程序博客网 时间:2024/05/21 09:53
求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;}
因为c在long long范围内,中间两个long long 相乘的时候会超long long。所以对乘法再写一个快速乘法的函数,将乘法变为加法,每加一次就进行取模,就不会超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 20using namespace std;const int maxn = 110;// a*b%cLL 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%cLL 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\n",ans);}return 0;}
求a^b%c (1 <= a,c <= 10^9, 1 <= b <= 10^1000000)
b相当大,快速幂超时。
有一个定理: a^b%c = a^(b%phi[c]+phi[c])%c,其中要满足b >= phi[c]。这样将b变为long long范围内的数,再进行快速幂。至于这个定理为什么成立,现在明白一点。这篇讲的挺详细: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 20using 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] = '\0';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;}}//对大整数取模,一位一位的取。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\n",ans);}return 0;}
0 0
- a^b%c 的三种形式
- oracle存储过程把'a,b,c'类型的值转换成'a','b','c'形式的值
- 关于A+B+C问题三种语言的解决办法,Java、C语言、Python
- 用火柴棒搭A+B=C形式的等式
- 关于Lintcode734形式为a^i b^j c^k的子序列数量
- 形式为a^i b^j c^k的子序列数量-LintCode
- LintCode 练习-734. 形式为a^i b^j c^k的子序列数量
- RIA c/s形式的b/s
- 'A,B,C'字符串转换为列形式
- 分别输出a*x*x+b*x+c=0的三种情况的根
- 对比函数形参的三种形式:int a,int *a,int &a
- C语言中整数的三种不同表达形式
- C语言main函数的三种形式
- 语句的三种形式
- 面试的三种形式
- b*b<4*a*c出现的
- 一张表中有三个值A/B/C,三者为A-B-C树状结构关系,如何查询出值C大于100的A值
- B从A获得信息的三种模式
- id ,NSObject, id<NSObject>区别
- Let's go home+hdu+2sat问题的求解
- Struts2_1_struts2运行环境的搭建
- 工作中的问题解决 -- (win2003 asp.net) Session和带页面回传的方法无法正常使用解决方案
- 《Android 4高级编程》学习摘要
- a^b%c 的三种形式
- Instance method '-copyPath:toPath:handler:' not found (return type defaults to 'id')
- STL中unique函数的用法
- the Marvelous Land of Oz 49%
- 【竞品分析】腾讯QQ手机浏览器与UC手机浏览器产品对比
- hdu 1785 You Are All Excellent
- 剑指offer 3.4 代码的鲁棒性2- 反转链表
- js跨浏览器事件处理程序
- SendMessage 异常捕获问题