题目大意:
求出长度为 n n n 的所有排列中所有最大值为 n n n 且最小值为 1 1 1 的子区间个数,对 998244353 998244353 998244353 取模。
思路:
设
1
1
1 的位置为
i
i
i ,
n
n
n 的位置为
j
j
j,也就是求
2
∗
(
n
−
2
)
!
∗
∑
i
=
1
n
∑
j
=
i
+
1
n
i
∗
(
n
−
j
+
1
)
2*(n-2)!*\sum_{i=1}^n\sum_{j=i+1}^ni*(n-j+1)
2∗(n−2)!∗i=1∑nj=i+1∑ni∗(n−j+1).
对于
∑
i
=
1
n
∑
j
=
i
+
1
n
i
∗
(
n
−
j
+
1
)
相当于
∑
i
=
1
n
∑
j
=
i
+
1
n
(
n
∗
i
−
j
∗
i
+
i
)
.
对于\sum_{i=1}^n\sum_{j=i+1}^ni*(n-j+1)相当于 \sum_{i=1}^n\sum_{j=i+1}^n(n*i-j*i+i).
对于i=1∑nj=i+1∑ni∗(n−j+1)相当于i=1∑nj=i+1∑n(n∗i−j∗i+i).
等于
∑
i
=
1
n
(
∑
j
=
i
+
1
n
n
∗
i
+
∑
j
=
i
+
1
n
i
−
∑
j
=
i
+
1
n
j
∗
i
)
.
等于 \sum_{i=1}^n( \sum_{j=i+1}^nn*i + \sum_{j=i+1}^ni- \sum_{j=i+1}^nj*i).
等于i=1∑n(j=i+1∑nn∗i+j=i+1∑ni−j=i+1∑nj∗i).
即
∑
i
=
1
n
(
(
n
−
i
)
∗
(
n
∗
i
+
i
)
−
i
∑
j
=
i
+
1
n
j
)
.
即\sum_{i=1}^n( (n-i)*(n*i + i)- i\sum_{j=i+1}^nj).
即i=1∑n((n−i)∗(n∗i+i)−ij=i+1∑nj).
也就是
∑
i
=
1
n
(
(
n
−
i
)
∗
(
n
∗
i
+
i
)
−
i
∗
(
i
+
1
+
n
)
∗
(
n
−
i
)
2
)
.
也就是\sum_{i=1}^n( (n-i)*(n*i + i)- i * \frac {(i+1 + n)*(n - i)}{2}).
也就是i=1∑n((n−i)∗(n∗i+i)−i∗2(i+1+n)∗(n−i)).
处理出
(
n
−
2
)
!
(n-2)!
(n−2)! 代入公式求解即可,注意取模。(这里需特判
n
=
1
n=1
n=1 的情况)
代码:
#include <bits/stdc++.h>
#define int long long
const int N = 1e5 + 10, mod = 998244353;
using namespace std;
using LL = long long;
signed main() {
int n;
cin >> n;
if (n == 1)
cout << 1;
else {
int val = 1;
for (int i = 1; i <= n - 2; i++) val = (val * i) % mod;
int ans = 0;
for (int i = 1; i <= n; i++) {
ans = (ans + (n - i) * (n * i + i) - i * (i + 1 + n) * (n - i) / 2) % mod;
}
cout << 2 * val * ans % mod;
}
}