解题思路
我们设f(n)为1到n的全排列的所有价值之和,可以发现,f(n)与f(n-1)密切相关。考虑如何从dp[n-1]生成dp[n],可以将1至n的价值分为两部分:n插入前序列的价值+插入n产生的价值。
解题代码
#include<bits/stdc++.h>
using namespace std;
int main(){
long long ans=0;
long long n;
cin>>n;
long long m=1;
long long MOD=998244353;
for(long long i=2;i<=n;i++) {
ans=((ans*i)%MOD+(i*(i-1)/2%MOD*m)%MOD)%MOD;
m=m*i%MOD;
}
cout<<ans;
return 0;
}
由于本题的n最高到了10^6,且涉及到阶乘,所以我们必须要使用long long 类型,但是即便如此,数值依然非常容易超出范围,因此设计好模运算颇为重要,例如,我们看下面的代码:
/*代码一*/
ans=(ans*i+m*i*(i-1)/2)%MOD;
再看下面的代码:
/*代码二*/
ans=((ans*i)%MOD+(i*(i-1)/2%MOD*m)%MOD)%MOD;
虽然代码一与代码二逻辑相同,但是代码一的非常容易超出范围,更难通过测试用例,得分更少。