C++ 有效地计算阶乘

C++ 有效地计算阶乘,c++,algorithm,data-structures,combinations,C++,Algorithm,Data Structures,Combinations,我有一个N高达10^5的数组。 我需要解决给定L和R的Q范围查询。 好的,因为根据你的评论,数组中只能有105个元素,这也是数组中每个可能值的最大计数 所以你可以做的一件事就是预先计算所有的阶乘到一个数组中,并使用它们进行计算 也许最好的办法是编写一个元程序,它将这些值构造成C++结构,然后可以在自己的代码段中包含这些值。结构将类似于: unsigned int facMod10p7[] = { 0, 1, 2, : /* whatever (10^5)!

我有一个N高达10^5的数组。 我需要解决给定L和R的Q范围查询。
好的,因为根据你的评论,数组中只能有105个元素,这也是数组中每个可能值的最大计数

所以你可以做的一件事就是预先计算所有的阶乘到一个数组中,并使用它们进行计算

也许最好的办法是编写一个元程序,它将这些值构造成C++结构,然后可以在自己的代码段中包含这些值。结构将类似于:

unsigned int facMod10p7[] = {
    0,
    1,
    2,
    :
    /* whatever (10^5)! % 1000000007 is */
};
一旦有了它,每个阶乘的查找都是O1。要进行查询,只需在数组中从L到R迭代,计算唯一值的数量

最好使用一个映射,其中第一个字段是假定此处为无符号值的值,但您也可以很容易地将此字段设为有符号,第二个字段是它发生的次数

对于{4,2,4}的L2/R4情况,您将得到一个如下的映射:

{ [2] = 1, [4] = 2 }
然后,简单地迭代,查找每个计数的阶乘,并取它们的乘积

由于它是On循环中的O1查找/乘法,因此产生的复杂性将是On

例如,一个Python程序在我的机器上输出前10000个阶乘大约需要30秒才能在我的WSL环境中生成整个表,不一定以其令人眼花缭乱的I/O速度著称,至少在即将发布的下一个版本之前:

real 0m29.137s
user 0m28.438s
sys  0m0.547s
如果您想自己进行测试,代码如下:

print('static unsigned int facMod10p7[] = {\n    0,')
val = 1
mult = 2
for i in range(100000):
    print('    {},'.format(val) % 1000000007)
    val *= mult
    mult += 1
print(');')

让我们考虑一下你的例子:

n = 7
A[n] = {5, 4, 2, 4, 5, 5, 7}
L = 2
R = 4
p = 1000000007
计算启用的[]的直方图H[]

在大小为n的数组中,介于L,R之间的所有值中,其中m是任意值的最大计数

 H[2] = 1
 H[3] = 0
 H[4] = 2
在代码中,类似于:

unsigned int facMod10p7[] = {
    0,
    1,
    2,
    :
    /* whatever (10^5)! % 1000000007 is */
};
int H[R-L+1],i;
对于i=L,iIs 10^5数组的最大大小或最大元素值?@paxdiablo 10^5是数组的最大大小。元素最多可为10^9所有阶乘均以100000007模计算。这是编程竞赛吗?如果是,请发布一个链接。如果竞赛仍在进行中,请不要询问和回答关于它的问题。关于数组中的查询,请参见示例。查询的答案是一个范围内不同元素计数的阶乘的乘积。10^5!有456574个数字。哎呀。@ggorlen:10^5!%1000000007最多有十个数字:-在任何情况下,这些数字只需要计算一次,并且生成的结构包含在代码中。例如,如果使用MPIR,这将是一个棘手的问题。@alex,在您提出的复杂性中,二次项来自哪里?如果在启用的情况下计算范围内的元素,阶乘查找和乘法现在为O1。这是On的结果。@n.m.,你可能应该把评论指向问题而不是答案。如果某个问题是无效的,那么应该删除它,并附上答案。但是人们,好吧,至少我会按照要求回答问题,因为我对它的有效性没有什么假设,当然,除了质量本身。
m = 2
F[] = { 0!,1!,2! }
F[] = { 0 ,1 ,2  }
j = F[H[0]]*F[H[1]]*F[H[2]] 
j = F[1]*F[0]*F[2] 
j = 1!*0!*2! 
j = 2 
//      1 2 3 4 5
H[] = { 0,1,0,2,3 }
m = 3
//      0 1 2 3
F[] = { 1,1,2,6 }
PI(F[H]) = F[0]*F[1]*F[0]*F[2]*F[3]
         =   1 *  1 *  1 *  2! * 3! 
         =   2*6
         =  12