您的位置:首页 > 其它

51Nod-1046 A^B Mod C 快速幂取模

2018-03-15 11:17 429 查看
题目链接:
          51Nod-1046 A^B Mod C

题目:
1046 A^B Mod C基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题给出3个正整数A B C,求A^B Mod C。例如,3 5 8,3^5 Mod 8 = 3。Input
3个正整数A B C,中间用空格分隔。(1 <= A,B,C <= 10^9)
Output
输出计算结果
Input示例
3 5 8
Output示例
3
题目分析:题目大意:
      求A的B次方模C的值第一反应:直接一步步算:#include <stdio.h>
int main()
{
//注意数据范围
long long int a,b,c,i,ans=1;
scanf("%lld%lld%lld",&a,&b,&c);
a%=c;//减小a的大小,先让a%c不影响结果
for (i=1; i<=b; i++)
ans=ans*a%c;//每一步都%c减小ans的大小,不影响结果
printf("%lld\n",ans);
return 0;
}显然,这样做的时间复杂度为O(b),如果b很大会时间超限。
所以我们选用快速幂取模的方法:  快速幂取模的思想:
令 k=(a*a)%c  , z=b/2 ;
如果b为偶数那么a^b%c 等同于  k ^ z % c;
如果b为奇数那么a^b%c 等同于  ((k^z  % c)*a  )% c ;

对于z , k'=(k*k)%c ,z'=z/2

如果z为偶数那么a^z%c 等同于  k' ^ z' % c;
如果z为奇数那么a^z%c 等同于  ((k'^z' % c)*a  )% c ;
于是我们发现这个过程可以迭代下去,直到 z 为0。
我们可以看出如果z是奇数需要额外再乘一遍 根号k  (即a) #include <stdio.h>
int main()
{
ll a,b,c,ans=1;
scanf("%lld%lld%lld",&a,&b,&c);
a%=c;
while(b)
{
if (b&1) // == b%2==1 判断z是否为奇数
ans=ans*a%c; // 这里的a相当于 根号k
b>>=1; // == b/2 即求z
a=a*a%c; // 求k
}
printf("%lld\n",ans);
return 0;
}如果没想明白,推荐一个博客:
http://blog.csdn.net/baidu_20363843/article/details/49559573
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  51Nod 快速幂取模