python - python 中无聊的阶乘

标签 python algorithm

我正在尝试理解并解决以下问题:

Sameer and Arpit want to overcome their fear of Maths and so they have been recently practicing Maths problems a lot. Aman, their friend has been helping them out. But as it goes, Sameer and Arpit have got bored of problems involving factorials. Reason being, the factorials are too easy to calculate in problems as they only require the residue modulo some prime and that is easy to calculate in linear time. So to make things interesting for them, Aman - The Mathemagician, gives them an interesting task. He gives them a prime number P and an integer N close to P, and asks them to find N! modulo P. He asks T such queries.

输入:

第一行包含一个整数 T,表示询问的数量。

接下来的 T 行包含 T 个形式为“N P”的查询。 (报价为 清晰度)

输出:

正好输出T行,包含N!模 P.

Example
Input:
3

2 5

5 11

21 71

Output:
2

10

6



Constraints:

1 <= T <= 1000

1 < P <= 2*10^9

1 <= N <= 2*10^9


Abs(N-P) <= 1000

现在我写了一个解决方案:

def factorial(c):
n1=1
n2=2
num=1
while num!=c:
    n1=(n1)*(n2)
    n2+=1
    num+=1
return n1


for i in range(int(raw_input())):
    n,p=map(int,raw_input().split())
    print factorial(n)%p

但如您所见,这是一个低效的解决方案,所以我开始寻找比我知道可以使用威尔逊和费米特定理解决这个问题更好的解决方案。但我无法理解作者想说的是什么 他说:

**在数论中,威尔逊定理指出自然数 n > 1 是素数当且仅当

enter image description here

现在我们可以这样写:

(p-1)!   ≡  -1 (mod p)

1*2*3*.........*(n-1)*(n)*..............*(p-1)  ≡   -1 (mod p)

n!*(n+1)*...........*(p-1)   ≡   -1 (mod p)

n!  ≡    -1*[(n+1)*...............(p-2)*(p-1)]^-1 (mod p)

let a=[(n+1)*...............(p-2)*(p-1)]

so

n!≡-1*a^-1(mod p)


From Fermat's Theorem:


a^(p-1) ≡ 1(mod p)

multiply both side by a^-1

a^(p-2)  ≡ a^-1(mod p)

now simply we have to find a^(p-2) mod p

**

所以我实现了这个:

def factorial1(n,p):            # to calculate  a=[(n+1)*...............(p-2)*(p-1)]
n0=n+1
n1=n0+1
while n1<=(p-1):
    n0=n1*n0
    n1+=1
return n0
# print nf(2,5)

for i in range(10):
    n,p=map(int,raw_input().split())
    if n>p:
        print 0
    elif n==p-1:
        print p-1
    else:
        print (factorial1(n,p)**(p-2))%p   #a^(p-2) mod p

但是从我得到的输出来看,我想我误解了他写的东西。有人能告诉我他告诉我要计算什么吗?我该如何编写他所说的代码。

最佳答案

这不是威尔逊定理的直接应用。连同它使用以下事实:

  • 如果n >= p然后n! = 0 (mod p)
  • 如果n < p然后n! = (p-1)!/[(n+1)(n+2)..(p-1)] .现在使用 (p-1)! = -1 (mod p) 的事实.剩下的就是modular multiplicative inverse。 (例如使用 extended Euclidean algorithm)的数字 n+1, n+2, ... , p-1哪个数最多为1000从事实上abs(n-p) <= 1000 .相乘(p-1)! = -1 (mod p)与数字的所有模乘逆n+1, n+2, ... , p-1你得到了答案。 (正如 John Coleman 指出的那样,您也可以对乘积进行逆运算而不是逆运算的乘积作为优化)

在你的情况下 n=2, p=5 (只是为了看看它是如何工作的)

n! = 2! = 4!/(3*4) = (-1)*2*4 = 2 (mod 5)

# 2 is modular inverse of 3 since 2*3 = 1 (mod 5)
# 4 is modular inverse of 4 since 4*4 = 1 (mod 5)

关于python - python 中无聊的阶乘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36792027/

相关文章:

java - 判断一个数独是否有唯一解

algorithm - Csv 与 Weka 如何添加逗号作为值而不是分隔符

database - 二进制搜索如何用于数据库索引

python - 如何展平/分割数组元组并计算 Polars 数据框中的列平均值?

python - ndimage.find_object ...颜色特征之后如何?

python - 删除两个字符之间的所有内容,包括字符

python - Keras/Tensorflow : ValueError: Shape (? ,12) 等级必须为 1

python - 循环中 'if'的多种组合多行条件

python - 4层嵌套字典转换为pandas dataframe python

python - 如何在 SPOJ 问题硬币中使用 Python 输入?