CF1278F Cards & 加强版

\[\begin{aligned} &\sum_{i=0}^n i^k \binom{n}{i} \left(\frac{1}{m}\right)^i \left(\frac{m-1}{m}\right)^{n-i} \\ =&\frac{1}{m^n}\sum_{i=0}^n i^k \binom{n}{i}(m-1)^{n-i} \\ =&\frac{1}{m^n}\sum_{i=0}^n \sum_{j=0}^k (m-1)^{n-i}\binom{n}{i}\binom{i}{j} \begin{Bmatrix}k\\j\end{Bmatrix} j! \\ =& \frac{1}{m^n}\sum_{i=0}^n \sum_{j=0}^k (m-1)^{n-i}\binom{n}{j}\binom{n-j}{i-j} \begin{Bmatrix}k\\j\end{Bmatrix} j! \\ =& \frac{1}{m^n} \sum_{j=0}^k n^{\underline{j}}\begin{Bmatrix}k\\j\end{Bmatrix}\sum_{i=0}^n(m-1)^{n-i}\binom{n-j}{i-j} \\ =& \frac{1}{m^n} \sum_{j=0}^k n^{\underline{j}}\begin{Bmatrix}k\\j\end{Bmatrix}\sum_{i=0}^n(m-1)^i\binom{n-j}{i} \\ =& \frac{1}{m^n} \sum_{j=0}^k n^{\underline{j}}\begin{Bmatrix}k\\j\end{Bmatrix}m^{n-j} \\ =& \sum_{j=0}^k n^{\underline{j}}\begin{Bmatrix}k\\j\end{Bmatrix}m^{-j} \\ \end{aligned}\]

使用 \(\mathcal{O}(k^2)\)\(\mathcal O(k\log k)\) 计算出一行的第二类斯特林数,然后计算这个式子,可以通过普通版。


为了方便书写后面令 \(p=m^{-1}\)

\[\begin{aligned} =& \sum_{j=0}^k n^{\underline{j}}\begin{Bmatrix}k\\j\end{Bmatrix}p^{j} \\ =& \sum_{j=0}^k \binom{n}{j}j!\frac{1}{j!}\sum_{i=0}^k(-1)^{j-i} (-p)^{j}i^k \binom{j}{i}\\ =& \sum_{j=0}^k \sum_{i=0}^k(-1)^i (-p)^{j}i^k \binom{n}{i}\binom{n-i}{j-i}\\ =& \sum_{i=0}^k (-1)^i\binom{n}{i} i^k\sum_{j=i}^k (-p)^{j} \binom{n-i}{j-i}\\ =& \sum_{i=0}^k \binom{n}{i} i^kp^{i}\sum_{j=0}^{k-i} (-p)^{j} \binom{n-i}{j}\\ \end{aligned}\]

\(\displaystyle S_i=\sum_{j=0}^{k-i}(-p)^j\binom{n-i}{j}\)

\[\begin{aligned} S_i&=\sum_{j=0}^{k-i}(-p)^j\binom{n-i}{j} \\ &=\sum_{j=0}^{k-i}(-p)^j\left(\binom{n-i-1}{j-1}+\binom{n-i-1}{j} \right) \\ &=-p\sum_{j=0}^{k-i-1}(-p)^j\binom{n-i-1}{j}+\sum_{j=0}^{k-i-1}(-p)^j\binom{n-i-1}{j}+(-p)^{k-i} \binom{n-i-1}{k-i} \\ &=(1-p)S_{i+1}+ (-p)^{k-i} \binom{n-i-1}{k-i}\\ \end{aligned}\]

当然边界 \(S_k=1\)

然后代入原式:

\[\begin{aligned} \sum_{i=0}^k \binom{n}{i} i^k p^{i}S_i\\ \end{aligned}\]

所有系数都可以 \(\mathcal O(k)\) 计算。

#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;

const int MAXN = 1e7 , Mod = 998244353;
int Add( int x , int y ) { x += y; return x >= Mod ? x - Mod : x; }
int Sub( int x , int y ) { x -= y; return x < 0 ? x + Mod : x; }
int Mul( int x , int y ) { return 1ll * x * y % Mod; }
int Qkpow( int x , int po ) { int Ans = 1; for( ; po ; po >>= 1 , x = Mul( x , x ) ) if( po & 1 ) Ans = Mul( Ans , x ); return Ans; }
int Inv( int x ) { return Qkpow( x , Mod - 2 ); }

int n , m , k , p[ MAXN + 5 ] , S[ MAXN + 5 ];

int fac[ MAXN + 5 ] , ivf[ MAXN + 5 ] , iv[ MAXN + 5 ];
int prnum , prime[ MAXN + 5 ] , idk[ MAXN + 5 ]; bool ip[ MAXN + 5 ];
void Init( ) {
	fac[ 0 ] = 1;
	for( int i = 1 ; i <= MAXN ; i ++ ) fac[ i ] = Mul( fac[ i - 1 ] , i );
    ivf[ MAXN ] = Inv( fac[ MAXN ] );
    for( int i = MAXN ; i >= 1 ; i -- ) ivf[ i - 1 ] = Mul( ivf[ i ] , i ); 
    iv[ 1 ] = 1;
    for( int i = 2 ; i <= MAXN ; i ++ ) iv[ i ] = Mul( iv[ Mod % i ] , Mod - Mod / i );

    idk[ 1 ] = 1;
    for( int i = 2 ; i <= MAXN ; i ++ ) {
        if( !ip[ i ] ) { prime[ ++ prnum ] = i; idk[ i ] = Qkpow( i , k ); }
        for( int j = 1 ; j <= prnum && 1ll * i * prime[ j ] <= MAXN ; j ++ ) {
            ip[ i * prime[ j ] ] = 1;
            idk[ i * prime[ j ] ] = Mul( idk[ i ] , idk[ prime[ j ] ] );
            if( i % prime[ j ] == 0 ) break;
        }
    }
}

int main( ) {
    scanf("%d %d %d",&n,&m,&k);
    
    Init();
    p[ 0 ] = 1; p[ 1 ] = Inv( m );
    for( int i = 2 ; i <= k ; i ++ ) p[ i ] = Mul( p[ i - 1 ] , p[ 1 ] );

    S[ k ] = 1;
    for( int i = k , c = 1 ; i >= 0 ; c = Mul( c , Mul( n + Mod - i , iv[ k - i + 1 ] ) ) , i -- )
        S[ i ] = Add( Mul( 1 + Mod - p[ 1 ] , S[ i + 1 ] ) , Mul( ( k - i ) & 1 ? Mod - p[ k - i ] : p[ k - i ] , c ) );
    
    int Ans = 0;
    for( int i = 0 , ci = 1 ; i <= k ; ci = Mul( ci , Mul( n + Mod - i , iv[ i + 1 ] ) ) , i ++ )
        Ans = Add( Ans , Mul( Mul( S[ i ] , idk[ i ] ) , Mul( ci , p[ i ] ) ) );
    printf("%d\n", Ans );
    return 0;
}
posted @ 2021-04-02 14:42  chihik  阅读(60)  评论(0编辑  收藏  举报