Raising Modulo Numbers

来源:互联网 发布:html a标签调用php文件 编辑:程序博客网 时间:2024/05/16 09:23

Time Limit: 1000MS
Memory Limit: 30000K
Total Submissions: 5506
Accepted: 3189

Description

People are different. Some secretly read magazines full of interesting girls’ pictures, others create 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 is 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 numbers. 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 division 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
(A1B1+A2B2+ … +AHBH)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

题意是第一行输入t代表有测试组数,第二行输入m表示对m求模,第三行输入n表示接下来要有n行数据,该n行数据每行包含2个数a,b;求这n个a^b的和,并计算该和对m求模的值

对于a^b,普通的求法是用一个循环一直乘b个a,这样的方法对于某些题目来说可能显得比较慢。
二分快速幂是一种利用b的二进制特征来快速求a^b的算法。
例如:
a = 2, b = 35,b的二进制表示形式为100011
则 a^b = (2^(2^5)) * (2^(2^1)) * (2^(2^0)),有了这样的思路之后,就不用循环b次了。
假设b的二进制表示有n位,从后往前依次为第1-n位,初始结果为1。则现在只需要从最后一位开始,若该位为0,则略过,若该位为1,则结果乘上a^(2^当前位序号)。最后得到的结果就是a^b了。这样循环执行的次数仅为b的二进制表示的位数,远小于b。

#include<cstdio>int m,a,b;//也要用long long型定义a,b,不然像第二个例子那种数据太大就会出错long long quickpow(long long x,long long y){    long long flag=1;    while(y)    {        if(y&1)//确认y是否为奇数            flag=(flag*x)%m;        x=(x*x)%m;        y/=2;//寻找下一位    }    return flag;}int main(){    int t,n;    scanf("%d",&t);    while(t--)    {        long long ans=0;        scanf("%d%d",&m,&n);        while(n--)        {            scanf("%lld%lld",&a,&b);            ans+=quickpow(a,b);            ans%=m;                 }        printf("%lld\n",ans);    }    return 0;}
0 0
原创粉丝点击