POJ1995(整数快速幂)

http://poj.org/problem?id=1995

题意:求(A1^B1 + A2^B2 + .....Ah^Bh)%M

直接快速幂,以前对快速幂了解不深刻,今天重新学了一遍so easy

以a^b为例:如果b是偶数那么一定可以写成 (a^2 * a^2 ....)一共是b/2个,那么其实就可以写成(a*a)^(b/2),另a = a*a,b= b/2,此时还是求a^b,只不过a和b已经变了,但是没有问题,还是可以按照上面的方法在判断的,如果b是奇数的话就把a的一个给拿出来先与ans相成,然后现在a的个数就是偶数,就可以按照偶数方法在划分;

2^8 : 8是偶数,a = a* a = 2 * 2= 4,b = b / 2 = 4;也就变成了 4^4,4还是偶数,a = 4 * 4 = 16,b= b / 2 = 2,也就变成了16 ^ 2,2还是偶数再分 a= a * a = 16 * 16,b = b / 2 = 1也就变成了 (16 * 16)^ 1,此时1是奇数ans * a就结束了,

2^5:5是奇数,先把一个2拿出来与ans相乘,ans * a = ans * 2,然后就可以划分了,a = a * a = 2 * 2 = 4,b= b / 2 = 2,也就变成了 4 ^ 2,此时的2是偶数,又可以把a与a相乘,a= a * a = 4 * 4 ,b = b / 2 = 1,也就变成了16^1,此时的b为奇数ans * a = 2 * 16;

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 int a,b,M,sum;
 8 int main()
 9 {
10     int t,h;
11     scanf("%d", &t);
12     while(t--)
13     {
14         scanf("%d%d",&M,&h);
15         sum = 0;
16         while(h--)
17         {
18             scanf("%d%d", &a,&b);
19             int ans = 1;
20             while(b)
21             {
22                 if(b & 1)
23                 {
24                     ans = (ans % M) * (a % M) % M;
25                 }
26                 a = (a % M ) * (a % M) % M;
27                 b = b >> 1;
28             }
29             sum = (sum + ans) % M;
30         }
31         printf("%d\n", sum);
32     }
33 
34     return 0;
35 }
View Code

 

posted @ 2015-12-21 17:00  zhaop  阅读(788)  评论(0编辑  收藏  举报