【问题标题】:Curious behaviour of inverse modulo反模的奇怪行为
【发布时间】: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&lt;&lt;"pow called with("&lt;&lt;a&lt;&lt;", "&lt;&lt;n&lt;&lt;", "&lt;&lt;p&lt;&lt;")\n"; 和循环中的cout&lt;&lt;"\ta: "&lt;&lt;a&lt;&lt;"\n"; 等等,看看会发生什么。您还可以测试溢出if(a &gt; numeric_limits&lt;decltype(a)&gt;::max()/2) cout&lt;&lt;"overflow";

标签: c++ primes factorial number-theory modular-arithmetic


【解决方案1】:

21!是 51090942171709440000,而 2^64 只是 1844674407370955161:所以如果 unsigned long long 是 64 位数量(很可能),它不适合。

【讨论】:

  • 我还没有计算出 21!我正在使用累积模式,所以这个数字永远不会大于 p
猜你喜欢
  • 2019-08-12
  • 2021-09-09
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-27
相关资源
最近更新 更多