D. New Year and the Permutation Concatenation
Let n n n be an integer. Consider all permutations on integers 1 to n n n in lexicographic order, and concatenate them into one big sequence p p p. For example, if n = 3 n=3 n=3, then p = [ 1 , 2 , 3 , 1 , 3 , 2 , 2 , 1 , 3 , 2 , 3 , 1 , 3 , 1 , 2 , 3 , 2 , 1 ] . p=[1,2,3,1,3,2,2,1,3,2,3,1,3,1,2,3,2,1]. p=[1,2,3,1,3,2,2,1,3,2,3,1,3,1,2,3,2,1]. The length of this sequence will be n ∗ n ! n*n! n∗n!.
Let 1 ≤ i ≤ j ≤ n ∗ n ! 1≤i≤j≤n*n! 1≤i≤j≤n∗n! be a pair of indices. We call the sequence ( p i , p i + 1 , … , p j − 1 , p j ) (p_i,p_{i+1},…,p_{j−1},p_j) (pi,pi+1,…,pj−1,pj) a subarray of p p p. Its length is defined as the number of its elements, i.e., j − i + 1 j-i+1 j−i+1. Its sum is the sum of all its elements, i.e., ∑ k = i j p k \sum_{k=i}^{j}{p_k} ∑k=ijpk.
You are given n n n. Find the number of subarrays of p p p of length n n n having sum n ∗ ( n + 1 ) 2 \frac{n*(n+1)}{2} 2n∗(n+1). Since this number may be large, output it modulo 998244353 998244353 998244353 (a prime number).
Input
The only line contains one integer n ( 1 ≤ n ≤ 1 0 6 ) n\ (1≤n≤10^6) n (1≤n≤106), as described in the problem statement.
Output
Output a single integer — the number of subarrays of length n n n having sum n ∗ ( n + 1 ) 2 \frac{n*(n+1)}{2} 2n∗(n+1), modulo 998244353.
Examples
input
3
output
9
input
4
output
56
input
10
output
30052700
Note
In the first sample, there are 16 subarrays of length 3. In order of appearance, they are:
[ 1 , 2 , 3 ] , [ 2 , 3 , 1 ] , [ 3 , 1 , 3 ] , [ 1 , 3 , 2 ] , [ 3 , 2 , 2 ] , [ 2 , 2 , 1 ] , [ 2 , 1 , 3 ] , [ 1 , 3 , 2 ] , [ 3 , 2 , 3 ] , [ 2 , 3 , 1 ] , [ 3 , 1 , 3 ] , [ 1 , 3 , 1 ] , [ 3 , 1 , 2 ] , [ 1 , 2 , 3 ] , [ 2 , 3 , 2 ] , [ 3 , 2 , 1 ] . [1,2,3], [2,3,1], [3,1,3], [1,3,2], [3,2,2], [2,2,1], [2,1,3], [1,3,2], [3,2,3], [2,3,1], [3,1,3], [1,3,1], [3,1,2], [1,2,3], [2,3,2], [3,2,1]. [1,2,3],[2,3,1],[3,1,3],[1,3,2],[3,2,2],[2,2,1],[2,1,3],[1,3,2],[3,2,3],[2,3,1],[3,1,3],[1,3,1],[3,1,2],[1,2,3],[2,3,2],[3,2,1].
Their sums are 6 , 6 , 7 , 6 , 7 , 5 , 6 , 6 , 8 , 6 , 7 , 5 , 6 , 6 , 7 , 6. 6, 6, 7, 6, 7, 5, 6, 6, 8, 6, 7, 5, 6, 6, 7, 6. 6,6,7,6,7,5,6,6,8,6,7,5,6,6,7,6. As n ∗ ( n + 1 ) 2 \frac{n*(n+1)}{2} 2n∗(n+1)=6, the answer is 9.
-
题意:
将一个含有1~n的所有排列按字典序排序并依次首尾拼接,问子序列(连续)的个数使得其元素和为 n ∗ ( n + 1 ) 2 \frac{n*(n+1)}{2} 2n∗(n+1) -
解法:
- 至于为什么这些子序列的长度都是n还不会证明。。
- 首先你得知道
c
+
+
c++
c++库函数
n
e
x
t
_
p
e
r
m
u
t
a
t
i
o
n
next\_permutation
next_permutation的实现原理:
-
/** Tips: next permuation based on the ascending order sort * sketch : * current: 3 7 6 2 5 4 3 1 . * | | | | * find i----+ j k +----end * swap i and k : * 3 7 6 3 5 4 2 1 . * | | | | * i----+ j k +----end * reverse j to end : * 3 7 6 3 1 2 4 5 . * | | | | * find i----+ j k +----end * */
-
具体方法为:
-
从后向前查找第一个相邻元素对 ( i , j ) (i,j) (i,j),并且满足 A [ i ] < A [ j ] ( i < j ) A[i] < A[j](i<j) A[i]<A[j](i<j)
易知,此时从j到end必然是降序。可以用反证法证明,请自行证明
-
在 [ j , e n d ) [j,end) [j,end)中寻找一个最小的 k k k使其满足 A [ i ] < A [ k ] A[i]<A[k] A[i]<A[k]
由于 [ j , e n d ) [j,end) [j,end)是降序的,所以必然存在一个k满足上面条件;并且可以从后向前查找第一个满足 A [ i ] < A [ k ] A[i]<A[k] A[i]<A[k]关系的 k k k,此时的 k k k必是待找的 k k k
-
将 A [ i ] A[i] A[i]与 A [ k ] A[k] A[k]交换
此时, i i i处变成比 i i i大的最小元素,因为下一个全排列必须是与当前排列按照升序排序相邻的排列,故选择最小的元素替代 i i i
易知,交换后的 [ j , e n d ) [j,end) [j,end)仍然满足降序排序。因为在 ( k , e n d ) (k,end) (k,end)中必然小于 i i i,在 [ j , k ) [j,k) [j,k)中必然大于 k k k,并且大于 i i i
-
逆置 [ j , e n d ) [j,end) [j,end)
由于此时 [ j , e n d ) [j,end) [j,end)是降序的,故将其逆置。最终获得下一全排序
-
注意:如果在步骤a)找不到符合的相邻元素对,即此时 i = b e g i n i=begin i=begin,则说明当前 [ b e g i n , e n d ) [begin,end) [begin,end)为一个降序顺序,即无下一个全排列, S T L STL STL的方法是将其逆置成升序
-
-
-
n
e
x
t
_
p
e
r
m
u
t
a
t
i
o
n
next\_permutation
next_permutation函数找到当前序列的一个比当前序列字典序大的最小字典序的排列,也就是对应了题目要求,那么本题我们可以这么想:对于可以构成
n
∗
(
n
+
1
)
2
\frac{n*(n+1)}{2}
2n∗(n+1)的连续子序列,他的位置有如下两种情况:
- 恰好为第 i i i个排列,可以发现所有的 n ! n! n!个排列都满足要求
- 或者是第 i i i个排列的后 k k k个与第 i + 1 i+1 i+1个排列的前 n − k n-k n−k个排列拼接而成
- 现在考虑后者:显然要使这 n n n个数恰好是一个排列的话,第i个排列的前 n − k n-k n−k个一定与第 i + 1 i+1 i+1个排列的前 n − k n-k n−k个相同,那么联系 n e x t p e r m u t a t i o n next_permutation nextpermutation的过程,不难发现,最长递减后缀长度 l e n < k len<k len<k才能满足,接下来统计会有多少区间
- 正难则反!直接统计不行的会方便很多:后 k k k位从 n n n个数中选出 k k k个递减依次放置在最后棉,方案数为 C n k C_{n}^{k} Cnk,前面 n − k n-k n−k个直接把剩下的排列就行了,方案数为 ( n − k ) ! (n-k)! (n−k)!,所以答案就是 n ∗ n ! − ∑ k = 1 n − 1 C n k ∗ ( n − k ) ! = n ∗ n ! − ∑ k = 1 n − 1 n ! k ! n*n!-\sum_{k=1}^{n-1}{C_{n}^{k}*(n-k)!} =n*n!-\sum_{k=1}^{n-1}{\frac{n!}{k!}} n∗n!−k=1∑n−1Cnk∗(n−k)!=n∗n!−k=1∑n−1k!n!
- 有大佬看出来这个题答案是下面这个式子: a n s [ n ] = ( a n s [ n − 1 ] + ( n − 1 ) ! − 1 ) ∗ n ans[n]=(ans[n-1]+(n-1)!-1)*n ans[n]=(ans[n−1]+(n−1)!−1)∗n
-
附代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=1e6+10;
int n;
ll fac[maxn];
ll quick_pow(ll a,ll b)
{
ll res=1LL;
while(b){
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
int main()
{
scanf("%d",&n);fac[0]=1LL;
for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
ll ans=1LL*n*fac[n]%mod;
for(int i=1;i<n;i++) ans=(ans-(fac[n]*quick_pow(fac[i],mod-2)%mod))%mod;
printf("%lld\n",(ans+mod)%mod);
}