博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Poj1995 Raising Modulo Numbers(快速幂)
阅读量:6456 次
发布时间:2019-06-23

本文共 2991 字,大约阅读时间需要 9 分钟。

Description

People are different. Some secretly read magazines full of interesting girls' pictures, others creat
e an A-bomb in their cellar, others like using Windows, and some like difficult mathematical games.
Latest marketing research shows, that this market segment was so far underestimated and that there i
s lack of such games. This kind of game was thus included into the KOKODáKH. The rules follow:Each
player chooses two numbers Ai and Bi and writes them on a slip of paper. Others cannot see the numbe
rs. In a given moment all players show their numbers to the others. The goal is to determine the sum
of all expressions AiBi from all players including oneself and determine the remainder after divisi
on by a given number M. The winner is the one who first determines the correct result. According to
the players' experience it is possible to increase the difficulty by choosing higher numbers.

You should write a program that calculates the result and is able to find out who won the game.

Input
The input consists of Z assignments.
The number of them is given by the single positive integer Z appearing on the first line of input.
Then the assignements follow.
Each assignement begins with line containing an integer M (1 <= M <= 45000).
The sum will be divided by this number.
Next line contains number of players H (1 <= H <= 45000).
Next exactly H lines follow. On each line, there are exactly two numbers Ai and Bi separated by space.
Both numbers cannot be equal zero at the same time.
Output
For each assingnement there is the only one line of output.
On this line, there is a number, the result of expression
(A1^B1+A2^B2+ ... +AH^BH)mod M.
Sample Input

3

16
4
2 3
3 4
4 5
5 6
36123
1
2374859 3029382
17
1
3 18132

Sample Output

2

13195
13

题意:求a的b次方对p取模的值,其中1<=a,b,p<=1000000000;

题解:根据数学常识,每一个正整数可以唯一表示为若干指数不重复的2的次幂的和。

也就是说,如果b在二进制表示下有k位,其中第i(0<=i<=k)位的数字是ci,那么:

\[ b=c_k 2^{k-1}+c_{k-1} 2^{k-2}+ ... +c_0 2^0 \]

于是:\[ a^b=a^{c_{k-1}*2^{k-1}}*a^{c_{k-2}*2^{k-2}}*...*a^{c_0*2^0} \]
因为$ k=\lceil log_2(b+1) \rceil $(其中 \(\lceil \rceil\) 表示向上取整),所以上式乘积项的数量不多于\(\lceil log_2(b+1) \rceil\) 个。又因为\(a^{2^i}=(a^{2{i-1}})^2\),所以我们很容易通过k次递归求出每个乘积项,当\(c_i=1\)时,把该乘积项累积到答案中。b&1 运算可以取出b在二进制表示下的最低位,而b>>1运算可以舍去最低位,在递推的过程中将二者结合,就可以遍历b在二进制表示下的所有数位\(c_i\)。整个算法的时间复杂度为\(O(log_2b)\)

代码如下:

#include
using namespace std;int read(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}int power(int a,int b,int p){ int ans=1%p; while(b) { if(b&1)ans=(long long)ans*a%p; a=(long long)a*a%p; b>>=1; } return ans;}int main(){ int T,k,a,b,n; T=read(); while(T--) { int ans=0; k=read();n=read(); for(int i=1;i<=n;i++) { a=read();b=read(); ans=(ans+power(a,b,k))%k; } printf("%d\n",ans); } return 0;}

转载于:https://www.cnblogs.com/Luvwgyx/p/8372245.html

你可能感兴趣的文章
Tiny语言执行环境TM机源码
查看>>
PE文件之资源讲解
查看>>
windows 7/mac编译cocos2d-x-3.2*的android工程报错
查看>>
MYSQL导入导出.sql文件(转)
查看>>
使用Elasticsearch、Logstash、Kibana与Redis(作为缓冲区)对Nginx日志进行收集(转)
查看>>
git review报错一例
查看>>
Tomcat在Linux上的安装与配置
查看>>
《信息安全系统设计基础》 课程教学
查看>>
Linux平台下使用rman进行oracle数据库迁移
查看>>
全栈工程师学习Linux技术的忠告
查看>>
iOS自定制tabbar与系统的tabbar冲突,造成第一次点击各个item图片更换选中,第二次选中部分item图片不改变...
查看>>
C# Dictionary用法总结
查看>>
SVN服务器使用(二)
查看>>
反射获取内部类以及调用内部类方法
查看>>
C语言 - pthread
查看>>
谈Linq To Sql的优劣--纯个人观点
查看>>
HDU 4996 Revenge of LIS(DP)
查看>>
App里面如何正确显示用户头像
查看>>
DATAGUARD维护:从库宕机后如何恢复到管理恢复模式
查看>>
Android中的PID和UID
查看>>