生活随笔
收集整理的這篇文章主要介紹了
Team Work(CF 932 E)[bzoj5093][Lydsy1711月赛]图的价值
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
0 前言
這是一道小清新題
1 題目相關(guān)
1.1傳送門
傳送門
1.2 題目大意
給出n,kn,k n , k ,求∑i=0n(ni)ik\sum_{i=0}^n\binom{n}{i}i^k i = 0 ∑ n ? ( i n ? ) i k 結(jié)果模109+710^9+7 1 0 9 + 7
1.3 數(shù)據(jù)范圍
n≤109,k≤5000n\le10^9,k\le5000 n ≤ 1 0 9 , k ≤ 5 0 0 0
2 算法
2.1 暴力
由于是cf題,所以不知道有什么好的部分分,大概暴力就是直接Θ(n)\Theta(n) Θ ( n ) 處理組合數(shù),遞推ii i 的次冪
2.2 正解
這道題直接算似乎難以優(yōu)化復(fù)雜度,畢竟nn n 太大了,我們考慮推式子 我們有個(gè)經(jīng)典的和第二類斯特林?jǐn)?shù)相關(guān)的結(jié)論 xn=∑i=0n{ni}xi↓x^n=\sum_{i=0}^n\begin{Bmatrix}n\\i\end{Bmatrix}x^{i\downarrow} x n = i = 0 ∑ n ? { n i ? } x i ↓ 證明 我們將其代入 ∑i=0n(ni)ik=∑i=0n(ni)∑j=0k{kj}ij↓=∑i=0n∑j=0k(ni){kj}ij↓=∑i=0n∑j=0k{kj}(ni)ij↓=∑i=0n∑j=0k{kj}n!i!(n?i)!?i!(i?j)!=∑i=0n∑j=0k{kj}(n?j)!(n?i)!(i?j)!?n!(n?j)!=∑i=0n∑j=0k{kj}(n?jn?i)nj↓=∑j=0k{kj}nj↓∑i=0n(n?jn?i)=∑j=0k{kj}nj↓2n?j\begin{aligned} \sum_{i=0}^n\binom{n}{i}i^k&=\sum_{i=0}^n\binom{n}{i}\sum_{j=0}^k\begin{Bmatrix}k\\j\end{Bmatrix}i^{j\downarrow}\\&=\sum_{i=0}^n\sum_{j=0}^k\binom{n}{i}\begin{Bmatrix}k\\j\end{Bmatrix}i^{j\downarrow}\\&=\sum_{i=0}^n\sum_{j=0}^k\begin{Bmatrix}k\\j\end{Bmatrix}\binom{n}{i}i^{j\downarrow}\\ &=\sum_{i=0}^n\sum_{j=0}^k\begin{Bmatrix}k\\j\end{Bmatrix}\frac{n!}{i!(n-i)!}·\frac{i!}{(i-j)!}\\ &=\sum_{i=0}^n\sum_{j=0}^k\begin{Bmatrix}k\\j\end{Bmatrix}\frac{(n-j)!}{(n-i)!(i-j)!}·\frac{n!}{(n-j)!}\\ &=\sum_{i=0}^n\sum_{j=0}^k\begin{Bmatrix}k\\j\end{Bmatrix}\binom{n-j}{n-i}n^{j\downarrow}\\ &=\sum_{j=0}^k\begin{Bmatrix}k\\j\end{Bmatrix}n^{j\downarrow}\sum_{i=0}^n\binom{n-j}{n-i}\\ &=\sum_{j=0}^k\begin{Bmatrix}k\\j\end{Bmatrix}n^{j\downarrow}2^{n-j}\\ \end{aligned} i = 0 ∑ n ? ( i n ? ) i k ? = i = 0 ∑ n ? ( i n ? ) j = 0 ∑ k ? { k j ? } i j ↓ = i = 0 ∑ n ? j = 0 ∑ k ? ( i n ? ) { k j ? } i j ↓ = i = 0 ∑ n ? j = 0 ∑ k ? { k j ? } ( i n ? ) i j ↓ = i = 0 ∑ n ? j = 0 ∑ k ? { k j ? } i ! ( n ? i ) ! n ! ? ? ( i ? j ) ! i ! ? = i = 0 ∑ n ? j = 0 ∑ k ? { k j ? } ( n ? i ) ! ( i ? j ) ! ( n ? j ) ! ? ? ( n ? j ) ! n ! ? = i = 0 ∑ n ? j = 0 ∑ k ? { k j ? } ( n ? i n ? j ? ) n j ↓ = j = 0 ∑ k ? { k j ? } n j ↓ i = 0 ∑ n ? ( n ? i n ? j ? ) = j = 0 ∑ k ? { k j ? } n j ↓ 2 n ? j ? 前面的推導(dǎo)中我們用到了二項(xiàng)式定理 我們發(fā)現(xiàn),化到最后,下降冪和2的冪次都是可以Θ(k)\Theta(k) Θ ( k ) 求的,我們現(xiàn)在要求的就是斯特林?jǐn)?shù)了,我們顯然會(huì)Θ(k2)\Theta(k^2) Θ ( k 2 ) 的遞推求斯特林?jǐn)?shù),那么就做完啦
代碼
到這里這個(gè)算法已經(jīng)可以通過此題了,貼出AC代碼
#include <cstdio>
#include <cctype>
#define rg register
typedef long long LL
;
template
< typename T
> inline T
max ( const T a
, const T b
) { return a
> b
? a
: b
; }
template
< typename T
> inline T
min ( const T a
, const T b
) { return a
< b
? a
: b
; }
template
< typename T
> inline void mind ( T
& a
, const T b
) { a
= a
< b
? a
: b
; }
template
< typename T
> inline void maxd ( T
& a
, const T b
) { a
= a
> b
? a
: b
; }
template
< typename T
> inline T
abs ( const T a
) { return a
> 0 ? a
: - a
; }
template
< typename T
> inline void swap ( T
& a
, T
& b
) { T c
= a
; a
= b
; b
= c
; }
template
< typename T
> inline T
gcd ( const T a
, const T b
) { if ( ! b
) return a
; return gcd ( b
, a
% b
) ; }
template
< typename T
> inline T
lcm ( const T a
, const T b
) { return a
/ gcd ( a
, b
) * b
; }
template
< typename T
> inline T
square ( const T x
) { return x
* x
; } ;
template
< typename T
> inline void read ( T
& x
)
{ char cu
= getchar ( ) ; x
= 0 ; bool fla
= 0 ; while ( ! isdigit ( cu
) ) { if ( cu
== '-' ) fla
= 1 ; cu
= getchar ( ) ; } while ( isdigit ( cu
) ) x
= x
* 10 + cu
- '0' , cu
= getchar ( ) ; if ( fla
) x
= - x
;
}
template
< typename T
> inline void printe ( const T x
)
{ if ( x
>= 10 ) printe ( x
/ 10 ) ; putchar ( x
% 10 + '0' ) ;
}
template
< typename T
> inline void print ( const T x
)
{ if ( x
< 0 ) putchar ( '-' ) , printe ( - x
) ; else printe ( x
) ;
}
const LL mod
= 1000000007 ;
int n
, k
, s
[ 5001 ] [ 5001 ] , bit
, ny
= 500000004 , xj
= 1 , ans
;
inline LL
pow ( LL x
, LL y
)
{ LL res
= 1 ; for ( ; y
; y
>>= 1 , x
= x
* x
% mod
) if ( y
& 1 ) res
= res
* x
% mod
; return res
;
}
int main ( )
{ read ( n
) , read ( k
) ; s
[ 0 ] [ 0 ] = 1 ; for ( rg
int i
= 1 ; i
<= k
; i
++ ) for ( rg
int j
= 1 ; j
<= i
; j
++ ) s
[ i
] [ j
] = ( ( LL
) j
* s
[ i
- 1 ] [ j
] + s
[ i
- 1 ] [ j
- 1 ] ) % mod
; bit
= pow ( 2ll , n
) ; for ( rg
int i
= 1 ; i
<= k
; i
++ ) xj
= ( LL
) xj
* ( n
- i
+ 1 ) % mod
, bit
= ( LL
) bit
* ny
% mod
, ans
= ( ( LL
) s
[ k
] [ i
] * xj
% mod
* bit
+ ans
) % mod
; print ( ans
) ; return 0 ;
}
3 優(yōu)化
3.1 加強(qiáng)版數(shù)據(jù)范圍
顯而易見,這道題可以優(yōu)化 瓶頸在求第二類斯特林?jǐn)?shù)上,我們可以用NTTNTT N T T 優(yōu)化復(fù)雜度,使得算法復(fù)雜度為O(klogk)\mathcal O(klogk) O ( k l o g k ) 然而本題的優(yōu)化需要非NTTNTT N T T 模數(shù)NTTNTT N T T ,所以會(huì)比較麻煩 update by 2019.3.5: 加推一題kk k 的數(shù)據(jù)范圍增強(qiáng)版 [bzoj5093][Lydsy1711月賽]圖的價(jià)值 我們發(fā)現(xiàn)這題的每個(gè)點(diǎn)都是獨(dú)立的,那么答案就是 n?2(n?12)?(∑i=0n?1(n?1i)?ik)n*2^{\binom{n-1}{2}}*\left(\sum_{i=0}^{n-1}\binom{n-1}{i}*i^k \right) n ? 2 ( 2 n ? 1 ? ) ? ( i = 0 ∑ n ? 1 ? ( i n ? 1 ? ) ? i k ) kk k 的范圍比較大,并且模數(shù)為998244353998244353 9 9 8 2 4 4 3 5 3 ,所以直接NTT預(yù)處理固定nn n 的第二類斯特林?jǐn)?shù)即可 代碼(多項(xiàng)式板子較長勿噴)
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <algorithm>
namespace fast_IO
{ const int IN_LEN
= 10000000 , OUT_LEN
= 10000000 ; char ibuf
[ IN_LEN
] , obuf
[ OUT_LEN
] , * ih
= ibuf
+ IN_LEN
, * oh
= obuf
, * lastin
= ibuf
+ IN_LEN
, * lastout
= obuf
+ OUT_LEN
- 1 ; inline char getchar_ ( ) { return ( ih
== lastin
) && ( lastin
= ( ih
= ibuf
) + fread ( ibuf
, 1 , IN_LEN
, stdin ) , ih
== lastin
) ? EOF : * ih
++ ; } inline void putchar_ ( const char x
) { if ( oh
== lastout
) fwrite ( obuf
, 1 , oh
- obuf
, stdout ) , oh
= obuf
; * oh
++ = x
; } inline void flush ( ) { fwrite ( obuf
, 1 , oh
- obuf
, stdout ) ; }
}
using namespace fast_IO
;
#define getchar() getchar_()
#define putchar(x) putchar_((x))
typedef long long ll
;
#define rg register
template
< typename T
> inline T
max ( const T a
, const T b
) { return a
> b
? a
: b
; }
template
< typename T
> inline T
min ( const T a
, const T b
) { return a
< b
? a
: b
; }
template
< typename T
> inline T
mind ( T
& a
, const T b
) { a
= a
< b
? a
: b
; }
template
< typename T
> inline T
maxd ( T
& a
, const T b
) { a
= a
> b
? a
: b
; }
template
< typename T
> inline T
abs ( const T a
) { return a
> 0 ? a
: - a
; }
template
< typename T
> inline void Swap ( T
& a
, T
& b
) { T c
= a
; a
= b
; b
= c
; }
template
< typename T
> inline void swap ( T
* a
, T
* b
) { T c
= a
; a
= b
; b
= c
; }
template
< typename T
> inline T
gcd ( const T a
, const T b
) { if ( ! b
) return a
; return gcd ( b
, a
% b
) ; }
template
< typename T
> inline T
square ( const T x
) { return x
* x
; } ;
template
< typename T
> inline void read ( T
& x
)
{ char cu
= getchar ( ) ; x
= 0 ; bool fla
= 0 ; while ( ! isdigit ( cu
) ) { if ( cu
== '-' ) fla
= 1 ; cu
= getchar ( ) ; } while ( isdigit ( cu
) ) x
= x
* 10 + cu
- '0' , cu
= getchar ( ) ; if ( fla
) x
= - x
;
}
template
< typename T
> void printe ( const T x
)
{ if ( x
>= 10 ) printe ( x
/ 10 ) ; putchar ( x
% 10 + '0' ) ;
}
template
< typename T
> inline void print ( const T x
)
{ if ( x
< 0 ) putchar ( '-' ) , printe ( - x
) ; else printe ( x
) ;
}
const int maxn
= 2097152 , mod
= 998244353 ;
inline int Md ( const int x
) { return x
>= mod
? x
- mod
: x
; }
template
< typename T
>
inline int pow ( int x
, T y
)
{ rg
int res
= 1 ; x
% = mod
; for ( ; y
; y
>>= 1 , x
= ( ll
) x
* x
% mod
) if ( y
& 1 ) res
= ( ll
) res
* x
% mod
; return res
;
}
namespace Poly
{
int W_
[ maxn
] , ha
[ maxn
] , hb
[ maxn
] , Inv
[ maxn
] ;
inline void init ( const int x
)
{ rg
int tim
= 0 , lenth
= 1 ; while ( lenth
< x
) lenth
<<= 1 , tim
++ ; for ( rg
int i
= 1 ; i
< lenth
; i
<<= 1 ) { const int WW
= pow ( 3 , ( mod
- 1 ) / ( i
* 2 ) ) ; W_
[ i
] = 1 ; for ( rg
int j
= i
+ 1 , k
= i
<< 1 ; j
< k
; j
++ ) W_
[ j
] = ( ll
) W_
[ j
- 1 ] * WW
% mod
; } Inv
[ 0 ] = Inv
[ 1 ] = 1 ; for ( rg
int i
= 2 ; i
< x
; i
++ ) Inv
[ i
] = ( ll
) ( mod
- mod
/ i
) * Inv
[ mod
% i
] % mod
;
}
int L
;
inline void DFT ( int * A
)
{ for ( rg
int i
= 0 , j
= 0 ; i
< L
; i
++ ) { if ( i
> j
) Swap ( A
[ i
] , A
[ j
] ) ; for ( rg
int k
= L
>> 1 ; ( j
^ = k
) < k
; k
>>= 1 ) ; } for ( rg
int i
= 1 ; i
< L
; i
<<= 1 ) for ( rg
int j
= 0 , J
= i
<< 1 ; j
< L
; j
+ = J
) for ( rg
int k
= 0 ; k
< i
; k
++ ) { const int x
= A
[ j
+ k
] , y
= ( ll
) A
[ j
+ k
+ i
] * W_
[ i
+ k
] % mod
; A
[ j
+ k
] = Md ( x
+ y
) , A
[ j
+ k
+ i
] = Md ( mod
+ x
- y
) ; }
}
void IDFT ( int * A
)
{ for ( rg
int i
= 1 ; i
< L
- i
; i
++ ) Swap ( A
[ i
] , A
[ L
- i
] ) ; DFT ( A
) ;
}
inline int Quadratic_residue ( const int a
)
{ if ( a
== 0 ) return 0 ; int b
= ( rand ( ) << 14 ^ rand ( ) ) % mod
; while ( pow ( b
, ( mod
- 1 ) >> 1 ) != mod
- 1 ) b
= ( rand ( ) << 14 ^ rand ( ) ) % mod
; int s
= mod
- 1 , t
= 0 , x
, inv
= pow ( a
, mod
- 2 ) , f
= 1 ; while ( ! ( s
& 1 ) ) s
>>= 1 , t
++ , f
<<= 1 ; t
-- , x
= pow ( a
, ( s
+ 1 ) >> 1 ) , f
>>= 1 ; while ( t
) { f
>>= 1 ; if ( pow ( ( int ) ( ( ll
) inv
* x
% mod
* x
% mod
) , f
) != 1 ) x
= ( ll
) x
* pow ( b
, s
) % mod
; t
-- , s
<<= 1 ; } return min ( x
, mod
- x
) ;
}
struct poly
{ std
: : vector
< int > A
; poly ( ) { A
. resize ( 0 ) ; } poly ( const int x
) { A
. resize ( 1 ) , A
[ 0 ] = x
; } inline int & operator
[ ] ( const int x
) { return A
[ x
] ; } inline int operator
[ ] ( const int x
) const { return A
[ x
] ; } inline void clear ( ) { A
. clear ( ) ; } inline unsigned int size ( ) const { return A
. size ( ) ; } inline void resize ( const unsigned int x
) { A
. resize ( x
) ; } void RE ( const int x
) { A
. resize ( x
) ; for ( rg
int i
= 0 ; i
< x
; i
++ ) A
[ i
] = 0 ; } void readin ( const int MAX
) { A
. resize ( MAX
) ; for ( rg
int i
= 0 ; i
< MAX
; i
++ ) read ( A
[ i
] ) ; } void putout ( ) const { for ( rg
unsigned int i
= 0 ; i
< A
. size ( ) ; i
++ ) print ( A
[ i
] ) , putchar ( ' ' ) ; } inline poly operator
+ ( const poly b
) const { poly RES
; RES
. resize ( max ( size ( ) , b
. size ( ) ) ) ; for ( rg
unsigned int i
= 0 ; i
< RES
. size ( ) ; i
++ ) RES
[ i
] = Md ( ( i
< size ( ) ? A
[ i
] : 0 ) + ( i
< b
. size ( ) ? b
[ i
] : 0 ) ) ; return RES
; } inline poly operator
- ( const poly b
) const { poly RES
; RES
. resize ( max ( size ( ) , b
. size ( ) ) ) ; for ( rg
unsigned int i
= 0 ; i
< RES
. size ( ) ; i
++ ) RES
[ i
] = Md ( ( i
< size ( ) ? A
[ i
] : 0 ) + mod
- ( i
< b
. size ( ) ? b
[ i
] : 0 ) ) ; return RES
; } inline poly operator
* ( const int b
) const { poly RES
= * this
; for ( rg
unsigned int i
= 0 ; i
< RES
. size ( ) ; i
++ ) RES
[ i
] = ( ll
) RES
[ i
] * b
% mod
; return RES
; } inline poly operator
/ ( const int b
) const { poly RES
= ( * this
) * pow ( b
, mod
- 2 ) ; return RES
; } inline poly operator
* ( const poly b
) const { const int RES
= A
. size ( ) + b
. size ( ) - 1 ; if ( A
. size ( ) <= 20 || b
. size ( ) <= 20 ) { poly c
; c
. RE ( RES
) ; for ( rg
unsigned int i
= 0 ; i
< size ( ) ; i
++ ) for ( rg
unsigned int j
= 0 ; j
< b
. size ( ) ; j
++ ) c
[ i
+ j
] = ( ( ll
) A
[ i
] * b
[ j
] + c
[ i
+ j
] ) % mod
; return c
; } L
= 1 ; while ( L
< RES
) L
<<= 1 ; poly c
; c
. A
. resize ( RES
) ; memset ( ha
, 0 , L
<< 2 ) ; memset ( hb
, 0 , L
<< 2 ) ; for ( rg
unsigned int i
= 0 ; i
< A
. size ( ) ; i
++ ) ha
[ i
] = A
[ i
] ; for ( rg
unsigned int i
= 0 ; i
< b
. A
. size ( ) ; i
++ ) hb
[ i
] = b
. A
[ i
] ; DFT ( ha
) , DFT ( hb
) ; for ( rg
int i
= 0 ; i
< L
; i
++ ) ha
[ i
] = ( ll
) ha
[ i
] * hb
[ i
] % mod
; IDFT ( ha
) ; const int inv
= pow ( L
, mod
- 2 ) ; for ( rg
int i
= 0 ; i
< RES
; i
++ ) c
. A
[ i
] = ( ll
) ha
[ i
] * inv
% mod
; return c
; } inline poly
inv ( ) const { poly C
; if ( A
. size ( ) == 1 ) { C
= * this
; C
[ 0 ] = pow ( C
[ 0 ] , mod
- 2 ) ; return C
; } C
. resize ( ( A
. size ( ) + 1 ) >> 1 ) ; for ( rg
unsigned int i
= 0 ; i
< C
. size ( ) ; i
++ ) C
[ i
] = A
[ i
] ; C
= C
. inv ( ) ; L
= 1 ; while ( L
< ( int ) size ( ) * 2 - 1 ) L
<<= 1 ; for ( rg
unsigned int i
= 0 ; i
< A
. size ( ) ; i
++ ) ha
[ i
] = A
[ i
] ; for ( rg
unsigned int i
= 0 ; i
< C
. size ( ) ; i
++ ) hb
[ i
] = C
[ i
] ; memset ( ha
+ A
. size ( ) , 0 , ( L
- A
. size ( ) ) << 2 ) ; memset ( hb
+ C
. size ( ) , 0 , ( L
- C
. size ( ) ) << 2 ) ; DFT ( ha
) , DFT ( hb
) ; for ( rg
int i
= 0 ; i
< L
; i
++ ) ha
[ i
] = ( ll
) ( 2 - ( ll
) hb
[ i
] * ha
[ i
] % mod
+ mod
) * hb
[ i
] % mod
; IDFT ( ha
) ; const int inv
= pow ( L
, mod
- 2 ) ; C
. resize ( size ( ) ) ; for ( rg
unsigned int i
= 0 ; i
< size ( ) ; i
++ ) C
[ i
] = ( ll
) ha
[ i
] * inv
% mod
; return C
; }
inline void Reverse ( const int n
) { A
. resize ( n
) ; for ( rg
int i
= 0 , j
= n
- 1 ; i
< j
; i
++ , j
-- ) Swap ( A
[ i
] , A
[ j
] ) ; } inline poly operator
/ ( const poly B
) const { if ( size ( ) < B
. size ( ) ) return 0 ; poly a
= * this
, b
= B
; a
. Reverse ( size ( ) ) , b
. Reverse ( B
. size ( ) ) ; b
. resize ( size ( ) - B
. size ( ) + 1 ) ; b
= b
. inv ( ) ; b
= b
* a
; b
. Reverse ( size ( ) - B
. size ( ) + 1 ) ; return b
; } inline poly operator
% ( const poly B
) const { poly C
= ( * this
) - ( * this
) / B
* B
; C
. resize ( B
. size ( ) - 1 ) ; return C
; } inline poly
diff ( ) const { poly C
; C
. resize ( size ( ) - 1 ) ; for ( rg
unsigned int i
= 1 ; i
< size ( ) ; i
++ ) C
[ i
- 1 ] = ( ll
) A
[ i
] * i
% mod
; return C
; } inline poly
inte ( ) const { poly C
; C
. resize ( size ( ) + 1 ) ; for ( rg
unsigned int i
= 0 ; i
< size ( ) ; i
++ ) C
[ i
+ 1 ] = ( ll
) A
[ i
] * Inv
[ i
+ 1 ] % mod
; C
[ 0 ] = 0 ; return C
; } inline poly
ln ( ) const { poly C
= ( diff ( ) * inv ( ) ) . inte ( ) ; C
. resize ( size ( ) ) ; return C
; } inline poly
exp ( ) const { poly C
; if ( size ( ) == 1 ) { C
= * this
; C
[ 0 ] = 1 ; return C
; } C
. resize ( ( size ( ) + 1 ) >> 1 ) ; for ( rg
unsigned int i
= 0 ; i
< C
. size ( ) ; i
++ ) C
[ i
] = A
[ i
] ; C
= C
. exp ( ) ; C
. resize ( size ( ) ) ; poly D
= ( poly
) 1 - C
. ln ( ) + * this
; D
= D
* C
; D
. resize ( size ( ) ) ; return D
; } inline poly
sqrt ( ) const { poly C
; if ( size ( ) == 1 ) { C
= * this
; C
[ 0 ] = Quadratic_residue ( C
[ 0 ] ) ; return C
; } C
. resize ( ( size ( ) + 1 ) >> 1 ) ; for ( rg
unsigned int i
= 0 ; i
< C
. size ( ) ; i
++ ) C
[ i
] = A
[ i
] ; C
= C
. sqrt ( ) ; C
. resize ( size ( ) ) ; C
= ( C
+ * this
* C
. inv ( ) ) * ( int ) 499122177 ; C
. resize ( size ( ) ) ; return C
; } inline poly operator
>> ( const unsigned int x
) const { poly C
; if ( size ( ) < x
) { C
. resize ( 0 ) ; return C
; } C
. resize ( size ( ) - x
) ; for ( rg
unsigned int i
= 0 ; i
< C
. size ( ) ; i
++ ) C
[ i
] = A
[ i
+ x
] ; return C
; } inline poly operator
<< ( const unsigned int x
) const { poly C
; C
. RE ( size ( ) + x
) ; for ( rg
unsigned int i
= 0 ; i
< size ( ) ; i
++ ) C
[ i
+ x
] = A
[ i
] ; return C
; } inline poly
Pow ( const unsigned int x
) const { for ( rg
unsigned int i
= 0 ; i
< size ( ) ; i
++ ) if ( A
[ i
] ) { poly C
= ( ( ( ( * this
/ A
[ i
] ) >> i
) . ln ( ) * x
) . exp ( ) * pow ( A
[ i
] , x
) ) << ( min ( i
* x
, size ( ) ) ) ; C
. resize ( size ( ) ) ; return C
; } return * this
; } inline void cheng ( const poly
& B
) { for ( rg
unsigned int i
= 0 ; i
< size ( ) ; i
++ ) A
[ i
] = ( ll
) A
[ i
] * B
[ i
] % mod
; } inline void jia ( const poly
& B
) { for ( rg
unsigned int i
= 0 ; i
< size ( ) ; i
++ ) A
[ i
] = Md ( A
[ i
] + B
[ i
] ) ; } inline void dft ( ) { memset ( ha
, 0 , L
<< 2 ) ; for ( rg
unsigned int i
= 0 ; i
< A
. size ( ) ; i
++ ) ha
[ i
] = A
[ i
] ; DFT ( ha
) ; resize ( L
) ; for ( rg
int i
= 0 ; i
< L
; i
++ ) A
[ i
] = ha
[ i
] ; } inline void idft ( ) { memset ( ha
, 0 , L
<< 2 ) ; for ( rg
unsigned int i
= 0 ; i
< A
. size ( ) ; i
++ ) ha
[ i
] = A
[ i
] ; IDFT ( ha
) ; const int inv
= pow ( L
, mod
- 2 ) ; for ( rg
int i
= 0 ; i
< L
; i
++ ) A
[ i
] = ( ll
) ha
[ i
] * inv
% mod
; while ( size ( ) && ! A
[ size ( ) - 1 ] ) A
. pop_back ( ) ; } ll
dai ( int x
) const { x
= Md ( x
% mod
+ mod
) ; ll res
= 0 ; for ( rg
unsigned int i
= 0 , j
= 1 ; i
< size ( ) ; i
++ , j
= ( ll
) j
* x
% mod
) res
= ( ( ll
) A
[ i
] * j
+ res
) % mod
; return res
; }
} ;
void fz ( const int root
, const int l
, const int r
, std
: : vector
< int > & v
, std
: : vector
< poly
> & A
)
{ if ( l
== r
) { A
[ root
] . resize ( 2 ) ; A
[ root
] [ 0 ] = ( mod
- v
[ l
] ) % mod
; A
[ root
] [ 1 ] = 1 ; return ; } const int mid
= ( l
+ r
) >> 1 ; fz ( root
<< 1 , l
, mid
, v
, A
) , fz ( root
<< 1 | 1 , mid
+ 1 , r
, v
, A
) ; A
[ root
] = A
[ root
<< 1 ] * A
[ root
<< 1 | 1 ] ;
}
void calc ( const int root
, const int l
, const int r
, std
: : vector
< int > & v
, std
: : vector
< poly
> & A
, std
: : vector
< poly
> & B
)
{ if ( l
== r
) { v
[ l
] = B
[ root
] [ 0 ] ; return ; } const int mid
= ( l
+ r
) >> 1 ; B
[ root
<< 1 ] = B
[ root
] % A
[ root
<< 1 ] ; B
[ root
<< 1 | 1 ] = B
[ root
] % A
[ root
<< 1 | 1 ] ; calc ( root
<< 1 , l
, mid
, v
, A
, B
) , calc ( root
<< 1 | 1 , mid
+ 1 , r
, v
, A
, B
) ;
}
void multi_point_evaluation ( const poly a
, std
: : vector
< int > & v
)
{ std
: : vector
< poly
> A
, B
; A
. resize ( maxn
) , B
. resize ( maxn
) ; fz ( 1 , 0 , v
. size ( ) - 1 , v
, A
) ; B
[ 1 ] = a
% A
[ 1 ] ; calc ( 1 , 0 , v
. size ( ) - 1 , v
, A
, B
) ;
}
void fz2 ( const int root
, const int l
, const int r
, std
: : vector
< int > & y
, std
: : vector
< poly
> & A
, std
: : vector
< poly
> & B
)
{ if ( l
== r
) { B
[ root
] . resize ( 1 ) , B
[ root
] [ 0 ] = y
[ l
] ; return ; } const int mid
= ( l
+ r
) >> 1 ; fz2 ( root
<< 1 , l
, mid
, y
, A
, B
) , fz2 ( root
<< 1 | 1 , mid
+ 1 , r
, y
, A
, B
) ; B
[ root
] = B
[ root
<< 1 ] * A
[ root
<< 1 | 1 ] + B
[ root
<< 1 | 1 ] * A
[ root
<< 1 ] ;
}
poly
interpolation ( std
: : vector
< int > & x
, std
: : vector
< int > & y
)
{ std
: : vector
< poly
> A
, B
; A
. resize ( maxn
) , B
. resize ( maxn
) ; fz ( 1 , 0 , x
. size ( ) - 1 , x
, A
) ; multi_point_evaluation ( A
[ 1 ] . diff ( ) , x
) ; for ( rg
unsigned int i
= 0 ; i
< x
. size ( ) ; i
++ ) y
[ i
] = ( ll
) y
[ i
] * pow ( x
[ i
] , mod
- 2 ) % mod
; fz2 ( 1 , 0 , x
. size ( ) - 1 , y
, A
, B
) ; return B
[ 1 ] ;
}
}
int n
, k
, bit
, ny
= 499122177 , xj
= 1 , ans
;
int fac
[ 500001 ] , inv
[ 500001 ] ;
Poly
: : poly a
, b
;
int main ( )
{ Poly
: : init ( maxn
) ; read ( n
) , read ( k
) , n
-- ; fac
[ 0 ] = 1 ; for ( rg
int i
= 1 ; i
<= k
; i
++ ) fac
[ i
] = ( ll
) fac
[ i
- 1 ] * i
% mod
; inv
[ k
] = pow ( fac
[ k
] , mod
- 2 ) ; for ( rg
int i
= k
; i
>= 1 ; i
-- ) inv
[ i
- 1 ] = ( ll
) inv
[ i
] * i
% mod
; a
. resize ( k
+ 1 ) , b
. resize ( k
+ 1 ) ; for ( rg
int i
= 0 ; i
<= k
; i
++ ) { a
[ i
] = inv
[ i
] ; if ( i
& 1 ) a
[ i
] = Md ( mod
- inv
[ i
] ) ; b
[ i
] = ( ll
) pow ( i
, k
) * inv
[ i
] % mod
; } a
= a
* b
; bit
= pow ( 2ll , n
) ; for ( rg
int i
= 1 ; i
<= k
; i
++ ) xj
= ( ll
) xj
* ( n
- i
+ 1 ) % mod
, bit
= ( ll
) bit
* ny
% mod
, ans
= ( ( ll
) a
[ i
] * xj
% mod
* bit
+ ans
) % mod
; print ( ( ll
) ans
* ( n
+ 1 ) % mod
* pow ( 2 , ( ll
) n
* ( n
- 1 ) / 2 ) % mod
) ; return flush ( ) , 0 ;
}
4 總結(jié)
不錯(cuò)的裸題,直接帶入就好了,貌似很多大佬都可以直接秒,算是一個(gè)斯特林?jǐn)?shù)的應(yīng)用吧
總結(jié)
以上是生活随笔 為你收集整理的Team Work(CF 932 E)[bzoj5093][Lydsy1711月赛]图的价值 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。