23.7.27 杭电暑期多校4部分题解

1010 - Kong Ming Qi

1005 - Data Generation

题目大意

有一个 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(n1), fi=(fi=1+2(n1)(n2)(n(n2))i2)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=fi1n2+2(n1)(n2)i1ni

分母为 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=(1pi1)n22(n1)+pi1n2n22

( 1 − p i − 1 ) ∗ 2 ( n − 1 ) n 2 (1-p_{i-1})*\frac{2(n-1)}{n^2} (1pi1)n22(n1) 是从无贡献变为有贡献的概率, p i − 1 ∗ n 2 − 2 n 2 p_{i-1}*\frac{n^2-2}{n^2} pi1n2n22 是有贡献继续产生贡献的概率

化简后可以得到 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(n1)+pi1nn2

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) n2pin(n1)=n(n2)pi1(n1)(n2)

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(npi(n1))=(n2)(npi1(n1))

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 npm(n1)=(nn2)m(np0(n1))=(n1)(nn2)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) npm=(n1)(1(nn2)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;
}

你可能感兴趣的:(数学)