【发布时间】:2013-11-13 14:54:07
【问题描述】:
我编写了以下代码来计算 n!modulo p...鉴于 n 和 p 很接近...但是它以一种相当有趣的方式运行,无法找出错误..某处有一些溢出..约束为 1
1
(a/b)mod p = ((a mod p)*(b^(p-2))mod p)mod p
因为p 是素数....和威尔逊定理(p-1)! mod p = p-1
#include<bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;
unsigned int pow(unsigned int a, unsigned n,unsigned int p) {
unsigned int ret = 1;
while(n) {
if((n&1)== 1) ret=(ret*a)%p;
a=a%p;
a=(a*a)%p;
n=n>>1;
}
return ret;
}
int main(){_
int t;
cin>>t;
while(t--){
unsigned int n,p;
long long int r;
cin>>n>>p;
r=p-1;
if(n>=p){
cout<<"0\n";
}
else{
for(unsigned int i=p-1;i>n;i--){
r=((long long)r*pow(i,p-2,p))%p;
}
cout<<r<<"\n";
}
}
return 0;
}
【问题讨论】:
-
#define _ ios_base::sync_with_stdio(0);cin.tie(0);oO 我从来没有见过 such 宏(我的意思是,我知道它的用途,但使用的标识符......让我无语了) -
我认为你的
a*=a已经溢出了。 Proof -
是的,你是对的,确实是溢出了
-
虽然它现在显示了 21!mod71 的正确答案,但它在指定的约束范围内溢出了其他数字,溢出发生在哪里?
-
添加跟踪器,如
cout<<"pow called with("<<a<<", "<<n<<", "<<p<<")\n";和循环中的cout<<"\ta: "<<a<<"\n";等等,看看会发生什么。您还可以测试溢出if(a > numeric_limits<decltype(a)>::max()/2) cout<<"overflow";
标签: c++ primes factorial number-theory modular-arithmetic