1. 程式人生 > 其它 >10388高階模運算

10388高階模運算

10388 高階模運算

題目描述

人與人是不同的,有些人喜歡閱讀滿是圖片的雜誌,有些人喜歡在地下室引爆炸彈,而還有一些卻喜歡一些麻煩的數字遊戲。比如ESSE論壇的一次活動:
每個人選擇兩個數字Ai和Bi寫在紙上,其他人不能看見。過了一段時間後,每個人說出自己紙上的數字,然後每個人的目標是求出所有的AiBi的和模M的值,最先算出結果的,就是勝利者。

輸入

第一行是一個數字M (1≤M≤45000)。第二行是數字H(1≤H≤45000)表示參加遊戲的人數。
接下來H行,每行兩個數Ai和Bi(1≤Ai,Bi≤2^31)。

輸出

輸出一個數字, ( A 1 B 1 A1^{B1}

A1B1 + A 2 B 2 A2^{B2} A2B2 + … + A n B n An^{Bn} AnBn) mod M 的值。

題目解析

我們需要求出每一個 A B A^{B} AB,如果直接使用for迴圈,時間開銷會超出限制,所以應當使用快速冪去求解。

快速冪思路

如果B為偶數,則 A B A^{B} AB= A B / 2 A^{B/2} AB/2 A B / 2 A^{B/2} AB/2
如果B為奇數,則 A B A^{B} AB= A B / 2 A^{B/2} AB/2
A B / 2 A^{B/2} AB/2*A(由於C++中除法向下取整)

AC程式碼

#include <iostream>
using namespace std; long long m,n,a,b; long long MyPow(long long x,long long y,long long m) { if(y==0) //A^0==1 { return 1; } else { long long ans=MyPow(x,y>>1,m); //ans=a^(b/2),使用移位操作代替除以2,能夠提升程式效能 if(!(y&1)) //二進位制表示下的偶數最後一位必定為0,所以可以用按位與計算是否為偶數
{ return (ans*ans)%m; } else { return (ans*ans*x)%m; } } } int main() { long long res=0; scanf("%I64d %I64d",&m,&n); while(n--) { scanf("%I64d %I64d",&a,&b); res+=(MyPow(a%m,b,m)); res%=m; } printf("%I64d\n",res); return 0; }

結果

程式碼AC,但是有個疑問,當我將全域性變數m,n,a,b設為區域性變數時,程式在OJ上執行超時,具體原因尚不清楚
執行結果截圖