【Sum(费马小定理+指数循环节公式)】
2014-07-26 14:54
363 查看
题目链接 HDU4704
【题意】就是求2^(n-1) % 1000000007 (n <= 10^100000)
【分析】由于n有100000位,所以直接快速幂也肯定超时,需要优化。
这里要使用到费马小定理;
费马小定理: gcd(a,m)=1(a,m互质) && m为素数,则a^(m-1)≡1 (mod m)
还需要用到一个公式(指数循环节):a^n ≡ a^(n % Phi(M) + Phi(M)) (mod M) (n >= Phi(M));Phi(M)在M为素数时为M-1,n>=Phi(M)的限制可以不用考虑(当然考虑了不会有错,n<Phi(M)的话完全可以直接用快速幂了,我测试了几组数据结果都是一样的)。
有关这个公式的证明可以参考(数学渣表示看不懂)http://hi.baidu.com/aekdycoin/item/e493adc9a7c0870bad092fd9
这样在这里这个公式可以写成 a^n ≡ a^(n%(m-1)+m-1) (mod m)(直接用这个公式复杂度已经很低了)
然后 因为1000000007是素数,并且gcd(2,1000000007) = 1,所以可以结合费马小定理化简上式:
a^n ≡ a^(n%(m-1)) * a^(m-1)≡ a^(n%(m-1)) (mod m)
这样求2^n-1 %1000000007只要求出(2^(n-1)%(1000000006)) %1000000007就可以了
【AC CODE(费马小定理+循环节公式)】0ms
其实可以只用循环节公式a^(n%(m-1)) * a^(m-1)就能简化了
【AC CODE(循环节公式)】0ms
【题意】就是求2^(n-1) % 1000000007 (n <= 10^100000)
【分析】由于n有100000位,所以直接快速幂也肯定超时,需要优化。
这里要使用到费马小定理;
费马小定理: gcd(a,m)=1(a,m互质) && m为素数,则a^(m-1)≡1 (mod m)
还需要用到一个公式(指数循环节):a^n ≡ a^(n % Phi(M) + Phi(M)) (mod M) (n >= Phi(M));Phi(M)在M为素数时为M-1,n>=Phi(M)的限制可以不用考虑(当然考虑了不会有错,n<Phi(M)的话完全可以直接用快速幂了,我测试了几组数据结果都是一样的)。
有关这个公式的证明可以参考(数学渣表示看不懂)http://hi.baidu.com/aekdycoin/item/e493adc9a7c0870bad092fd9
这样在这里这个公式可以写成 a^n ≡ a^(n%(m-1)+m-1) (mod m)(直接用这个公式复杂度已经很低了)
然后 因为1000000007是素数,并且gcd(2,1000000007) = 1,所以可以结合费马小定理化简上式:
a^n ≡ a^(n%(m-1)) * a^(m-1)≡ a^(n%(m-1)) (mod m)
这样求2^n-1 %1000000007只要求出(2^(n-1)%(1000000006)) %1000000007就可以了
【AC CODE(费马小定理+循环节公式)】0ms
#include <cstdio> #include <cstring> #include <cmath> typedef long long LL; #define MAXN 100010 #define MOD 1000000007 char c[MAXN]; int pow_mod(LL a, int n) { LL ans = 1; while(n) { if(n&1) ans = ans*a%MOD; a = a*a%MOD; n >>= 1; } return ans; } int main() { #ifdef SHY freopen("e:\\1.txt","r",stdin); #endif while(~scanf("%s%*c", c)) { LL n = 0; for(int i = 0;c[i];i++) n = (n*10%(MOD-1)+c[i]-'0')%(MOD-1); printf("%d\n", pow_mod(2,(n-1+MOD-1)%(MOD-1))); } return 0; }
其实可以只用循环节公式a^(n%(m-1)) * a^(m-1)就能简化了
【AC CODE(循环节公式)】0ms
#include <cstdio> #include <cstring> #include <cmath> typedef long long LL; #define MAXN 100010 #define MOD 1000000007 char c[MAXN]; int pow_mod(LL a, int n) { LL ans = 1; while(n) { if(n&1) ans = ans*a%MOD; a = a*a%MOD; n >>= 1; } return ans; } int main() { #ifdef SHY freopen("e:\\1.txt","r",stdin); #endif while(~scanf("%s%*c", c)) { LL n = 0; for(int i = 0;c[i];i++) n = (n*10%(MOD-1)+c[i]-'0')%(MOD-1); printf("%I64d\n", ((LL)pow_mod(2,(n-1+MOD-1)%(MOD-1))*pow_mod(2,MOD-1))%MOD); } return 0; }
相关文章推荐
- hdu 5728 (公式推导+指数循环节)
- 【HDU 5895】【指数循环节 矩阵 快速幂 逆元 推公式】Mathematician QSC 由递推式推公式
- POJ 1845 Sumdiv 【推公式 | 逆元】
- Super A^B mod C(指数循环节+欧拉函数)
- HDU2837 Calculation【指数循环节】
- 【关于 A^x = A^(x % Phi(C) + Phi(C)) (mod C) 的若干证明】【指数循环节
- 指数循环节 求A的B次方模C
- HDU 5690 查找循环节 数学公式快速幂+乘法逆元(除法取模)
- 【POJ 1845】 Sumdiv (整数唯分+约数和公式+二分等比数列前n项和+同余)
- 费马小定理,欧拉定理,指数循环节
- HDU 2837 Calculation (指数循环节)
- poj-1845 Sumdiv (逆元+费马小定理+因子和)
- hdu 5895 Mathematician QSC 指数循环节+矩阵快速幂
- HDU 5895 矩阵快速幂+欧拉降幂公式+指数循环节
- [ACM] POJ 1845 Sumdiv(求A的B次方的所有因子的和,一大堆数学公式...,可做模板)
- 上帝与集合的正确用法 HYSBZ - 3884 (指数循环节)
- 指数循环节与高精度取模
- HDU1005-数学公式+循环节
- POJ 1845-Sumdiv(快速幂取模+整数唯一分解定理+约数和公式+同余模公式)
- Codeforces Round #362 (Div. 1) C PLEASE(组合数学,指数循环节)