2015 CSUST校赛 - 超级快速幂【费马小定理】+【快速幂取模】



超级快速幂

Time Limit: 3000/1000 MS(Java/Others)   Memory Limit:65536/65536 K (Java/Others)

Description

 

请计算:   


a^(b^c)mod(1e9+7)

Input

 

多组数据,第一行为一个整数T,代表数据组数,接下来每行三个整数a,b,c1<=a,b,c<=1,000,000,000

 

Output

 

对于每组数据,输出一行代表计算结果

 

Sample Input

 

2

1 2 3

2 3 2

 

Sample Output

 

1

512


解题思路:

首先,不能直接算a^(b^c % mod) % mod

正确的做法是根据费马小定理,当a和mod互质时,有 a^(mod-1) % mod = 1

费马小定理的证明请参考维基百科:http://zh.wikipedia.org/wiki/%E8%B4%B9%E9%A9%AC%E5%B0%8F%E5%AE%9A%E7%90%86
所以a^(b^c)%mod=a^( b^c % (mod-1) ) %mod
然后直接套用快速幂的模板即可

比如【对照例子理解代码更Easy哦】:

计算 2^{100}除以13的余数
2^{100} \equiv 2^{12 \times 8+4} \pmod{13}
\equiv (2^{12})^8 \cdot  2^4 \pmod{13}
\equiv 1^8 \cdot  16 \pmod{13}
\equiv 16 \pmod{13}
\equiv 3 \pmod{13}

//先给出快速幂模板

int power_mod(LL a, LL b, LL P)
{
    if(b == 0) return 1;
    LL ans = power_mod(a, b >> 1, P);
    ans = ans * ans % P;
    return (int)(b & 1) ? a % P * ans % P: ans;
}
//超级快速幂化简的推导过程【对照实例理解】:
//div = (b^c) / (mod-1);
//rem = (b^c) % (mod-1);	// rem < mod

int rem = power_mod(b,c,mod-1);

//   a^(b^c) % mod
// = a^((mod-1)*div + rem) % mod
// = a^rem % mod

int ans = power_mod(a,rem,mod);
最后,发现原来超级快速幂也就是小case,是不是?

Tips : 这个题其实是可以用欧拉函数,指数循环节做的,追根溯源,本质其实是一样的,费马小定理是欧拉函数的一个特例而已!!

你可能感兴趣的:(ACM____数,学)