算法竞赛中阶乘之和的优化
输出\((1!+2+3!+..+n!)\%MOD\),其中MOD = 1000000。
书本给出的源代码
int f(int n)
{
int S = 0;
for(int i = 1;i <= n;++i)
{
int factorial = 1;
for(int j = 1;j <= i;++j)
factorial = (factorial*j) % MOD;
S = (S + factorial) % MOD;
}
return S;
}
\((1!+2!+3!+...(n-1)!+n!)\%MOD=(1!\%MOD+2!\%MOD+...+(n-1)!\%MOD+n!\%MOD)\%MOD\),建立前后相邻两个加项的关系,\(n!\%MOD=n*((n-1)!\%MOD)=((n\%MOD)*((n-1)!\%MOD))\%MOD=...\)不断递推得到第一项。
int f(int n)
{
int S = 0,tempS = 1;
for(int i = 1;i <= n;++i)
{
tempS = tempS * i % MOD;
S = (S + tempS) % MOD;
}
return S;
}
其实这里,准确来说的话,tempS = tempS * i % MOD
应该换成tempS = tempS * (i % MOD) %MOD
,但由于给的数据,明显这一步是多余的
其实通过数据运算,我们可以得到25!后面恰好有6个零,也就是说后面项的加入不会影响最终结果。
int f2(int n)
{
if(n > 25) n = 25;
int S = 0,tempS = 1;
for(int i = 1;i <= n;++i)
{
tempS = tempS * i % MOD;
S = (S + tempS) % MOD;
}
return S;
}