10388高階模運算
阿新 • • 發佈:2021-04-27
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上執行超時,具體原因尚不清楚