首页 > 其他 > 详细

P4091 [HEOI2016/TJOI2016]求和

时间:2021-04-01 00:35:34      阅读:31      评论:0      收藏:0      [点我收藏+]

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

卷积形式,直接 ntt \(\mathcal{O(n \log n)}\) 解决。

注意等比数列特判 \(j-k=1\) 的情况。

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

const int MAXN = 4e5 , 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 fac[ MAXN + 5 ] , ivf[ 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 );
}

#define Poly vector< int >
#define len( x ) ( (int)x.size() )
const int G = 3 , IG = 332748118;
int lim , ilim , rev[ MAXN + 5 ];
void ntt( Poly &f , int op ) {
	for( int i = 0 ; i < lim ; i ++ ) if( i < rev[ i ] ) swap( f[ i ] , f[ rev[ i ] ] );
	for( int len = 2 , w ; len <= lim ; len <<= 1 ) {
		w = Qkpow( op == 1 ? G : IG , ( Mod - 1 ) / len );
		for( int l = 0 ; l < lim ; l += len ) {
			for( int i = l , wk = 1 ; i < l + len / 2 ; i ++ , wk = Mul( wk , w ) ) {
				int t = Mul( wk , f[ i + len / 2 ] );
				f[ i + len / 2 ] = Sub( f[ i ] , t ); f[ i ] = Add( f[ i ] , t );
			}
		}
	}
	if( op == -1 ) for( int i = 0 ; i < lim ; i ++ ) f[ i ] = Mul( f[ i ] , ilim );
}
Poly operator * ( Poly f , Poly g ) {
	int n = len( f ) + len( g ) - 1; for( lim = 1 ; lim < n ; lim <<= 1 ); ilim = Inv( lim );
	for( int i = 0 ; i < lim ; i ++ ) rev[ i ] = ( rev[ i >> 1 ] >> 1 ) | ( i & 1 ? lim >> 1 : 0 );
	f.resize( lim ); g.resize( lim );
	ntt( f , 1 ); ntt( g , 1 );
	for( int i = 0 ; i < lim ; i ++ ) f[ i ] = Mul( f[ i ] , g[ i ] );
	ntt( f , -1 ); f.resize( n ); 
	return f;
}

Poly f , g;
int n;
int main( ) {
    
    Init();
    scanf("%d",&n); f.resize( n + 1 ) , g.resize( n + 1 );
    for( int i = 0 ; i <= n ; i ++ ) {
        f[ i ] = i & 1 ? Mod - ivf[ i ] : ivf[ i ];
        g[ i ] = Mul( Sub( 1 , Qkpow( i , n + 1 ) ) , Inv( Mul( Sub( 1 , i ) , fac[ i ] ) ) );
    }
    g[ 1 ] = n + 1;
    f = f * g;
    int Ans = 0;
    for( int i = 0 ; i <= n ; i ++ )
        Ans = Add( Ans , Mul( Mul( Qkpow( 2 , i ) , fac[ i ] ) , f[ i ] ) );
    printf("%d\n", Ans );
    return 0;
}

P4091 [HEOI2016/TJOI2016]求和

原文:https://www.cnblogs.com/chihik/p/P4091.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!