1. 程式人生 > >【洛谷】P4705 玩遊戲-生成函式

【洛谷】P4705 玩遊戲-生成函式

傳送門:luoguP4705


題解

t t 次價值的期望: 1 n m

i = 1 n j
= 1
m
( a i +
b j ) t \dfrac{1}{nm}\sum\limits_{i=1}^n\sum\limits_{j=1}^m\sum(a_i+b_j)^t

二項式定理展開一下:
t ! n m k = 0 t 1 k ! i = 1 n a i k 1 ( t k ) ! j = 1 m b j t k \dfrac{t!}{nm}\sum\limits_{k=0}^t\dfrac {1}{k!}\sum\limits_{i=1}^na_i^k\dfrac{1}{(t-k)!}\sum\limits_{j=1}^mb_j^{t-k}

所以需要構造的生成函式 F ( x ) , G ( x ) F(x),G(x) 的第 i i 項係數分別為 j = 1 n a j i , j = 1 m b j i \sum\limits_{j=1}^na_j^i,\sum\limits_{j=1}^mb_j^i

單獨考慮 a j a_j F F 的貢獻: 1 + a i x + a i 2 x + . . . 1+a_ix+a_i^2x+... ,生成函式為 1 1 a j x \dfrac1{1-a_jx}
所以 F ( x ) = i = 1 n 1 1 a i x F(x)=\sum\limits_{i=1}^n\dfrac1{1-a_ix}

1 a i x 1-a_ix 在分母不好看,積分轉成 l n ln ,得到 F ( x ) = i = 1 n ln ( 1 a i x ) F(x)=\sum\limits_{i=1}^n\ln'(1-a_ix)

還是不好看。。。再把求導轉到整個函式外面:

F ( x ) = ( ln ( i = 1 n ( 1 a i x ) ) ) F'(x)=(\ln(\prod\limits_{i=1}^n(1-a_ix)))'

F = x F + n F=-xF'+n

G G 同理,然後套多項式模板即可。


程式碼

#include<bits/stdc++.h>
#define mem(f) memset(f,0,sizeof(f))
using namespace std;
typedef long long ll;
const int N=1e5+10,M=2e6+10,mod=998244353,gen=3;

int n,m,bs,ivg,a[M],b[M],f[M],g[M];
int rv[M],s[20][M],frac[N],nv[N];

char cp,OS[100];
inline void rd(int &x)
{
    cp=getchar();x=0;
    for(;!isdigit(cp);cp=getchar());
    for(;isdigit(cp);cp=getchar()) x=(x<<3)+(x<<1)+(cp^48);
}

inline void ot(int x)
{
	int re=0;OS[0]='\n';
	for(;(!re)||x;x/=10) OS[++re]='0'+x%10;
	for(;~re;--re) putchar(OS[re]);
}

inline int ad(int x,int y){x+=y;return x>=mod?x-mod:x;}
inline int dc(int x,int y){x-=y;return x<0?x+mod:x;}

inline int fp(int x,int y)
{
    int re=1;
    for(;y;y>>=1,x=(ll)x*x%mod)
      if(y&1) re=(ll)re*x%mod;
    return re;
}

inline void ntt(int *e,int pr,int n)
{
    int i,j,k,ix,iy,ori,pd,g=pr?gen:ivg;
    for(i=1;i<n;++i) if(i<rv[i]) swap(e[i],e[rv[i]]);
    for(i=1;i<n;i<<=1){
        ori=fp(g,(mod-1)/(i<<1));
        for(j=