题目大意
有一个 1 1 1 到 n n n 的顺序排列,交换 n n n 次,问期望有多少个数不在原来的位置上
解题思路
第一感觉是一个打表找规律的题,那么先打表再说
打完之后就硬推式子找规律
对于同一行的分子 f i f_i fi, f 1 = 2 n ( n − 1 ) , f i = ( f i = 1 + 2 ( n − 1 ) ( n − 2 ) ∗ ( n ( n − 2 ) ) i − 2 ) ∗ n 2 f_1=2n(n-1),\space f_i=(f_{i=1}+2(n-1)(n-2)*(n(n-2))^{i-2})*n^2 f1=2n(n−1), fi=(fi=1+2(n−1)(n−2)∗(n(n−2))i−2)∗n2
化简后 f i = f i − 1 ∗ n 2 + 2 ( n − 1 ) ( n − 2 ) i − 1 n i f_i=f_{i-1}*n^2+2(n-1)(n-2)^{i-1}n^i fi=fi−1∗n2+2(n−1)(n−2)i−1ni
分母为 n 2 m n^{2m} n2m
可以用矩阵快速幂来处理,但是不太会,通项公式也推不出来,正赛上就止步于此了
赛后换了个思路考虑
假设某个数在第 i i i 次有贡献的概率为 p i p_i pi,那么 p 0 = 0 , p i = ( 1 − p i − 1 ) ∗ 2 ( n − 1 ) n 2 + p i − 1 ∗ n 2 − 2 n 2 p_0=0,\space p_i=(1-p_{i-1})*\frac{2(n-1)}{n^2}+p_{i-1}*\frac{n^2-2}{n^2} p0=0, pi=(1−pi−1)∗n22(n−1)+pi−1∗n2n2−2
( 1 − p i − 1 ) ∗ 2 ( n − 1 ) n 2 (1-p_{i-1})*\frac{2(n-1)}{n^2} (1−pi−1)∗n22(n−1) 是从无贡献变为有贡献的概率, p i − 1 ∗ n 2 − 2 n 2 p_{i-1}*\frac{n^2-2}{n^2} pi−1∗n2n2−2 是有贡献继续产生贡献的概率
化简后可以得到 p i = 2 ( n − 1 ) n 2 + p i − 1 ∗ n − 2 n p_i=\frac{2(n-1)}{n^2}+p_{i-1}*\frac{n-2}{n} pi=n22(n−1)+pi−1∗nn−2
n 2 ∗ p i − n ∗ ( n − 1 ) = n ∗ ( n − 2 ) ∗ p i − 1 − ( n − 1 ) ∗ ( n − 2 ) n^2*p_i-n*(n-1)=n*(n-2)*p_{i-1}-(n-1)*(n-2) n2∗pi−n∗(n−1)=n∗(n−2)∗pi−1−(n−1)∗(n−2)
n ∗ ( n ∗ p i − ( n − 1 ) ) = ( n − 2 ) ∗ ( n ∗ p i − 1 − ( n − 1 ) ) n*(n*p_i-(n-1))=(n-2)*(n*p_{i-1}-(n-1)) n∗(n∗pi−(n−1))=(n−2)∗(n∗pi−1−(n−1))
n ∗ p m − ( n − 1 ) = ( n − 2 n ) m ∗ ( n ∗ p 0 − ( n − 1 ) ) = − ( n − 1 ) ∗ ( n − 2 n ) m n*p_m-(n-1)=(\frac{n-2}{n})^m*(n*p_0-(n-1))=-(n-1)*(\frac{n-2}{n})^m n∗pm−(n−1)=(nn−2)m∗(n∗p0−(n−1))=−(n−1)∗(nn−2)m
因为总共有 n n n 个数,所以最后的答案要乘 n n n
所以答案 n ∗ p m = ( n − 1 ) ∗ ( 1 − ( n − 2 n ) m ) n*p_m=(n-1)*(1-(\frac{n-2}{n})^m) n∗pm=(n−1)∗(1−(nn−2)m)
code
#include
using namespace std;
const long long MOD = 998244353;
int t;
long long n, m;
long long sub(long long a, long long b) {return a - b < 0 ? a - b + MOD : a - b;}
long long mul(long long a, long long b) {return a * b % MOD;}
long long pw(long long a, long long b) {
long long res = 1;
while (b) {
if (b & 1) res = mul(res, a);
a = mul(a, a);
b >>= 1;
}
return res;
}
int main() {
scanf("%d", &t);
while (t --) {
scanf("%lld%lld", &n, &m); n %= MOD;
printf("%lld\n", mul(sub(n, 1), sub(1, pw(mul(sub(n, 2), pw(n, MOD - 2)), m))));
}
return 0;
}