洛谷5月月賽 玩遊戲(NTT,生成函式)

2021-08-20 17:13:15 字數 3182 閱讀 8457

luogu

看一下要求的是什麼東西 (a

x+by

)i( ax

+by)

i的期望。期望顯然是所有答案和的平均數。

所以求出所有的答案就在乘乙個逆元就好了。

現在考慮怎麼算上面那個東西。

對於單個的計算,我們可以用二項式定理直接展開

得到 ∑(a

+b)k

=∑∑i

=0kc

ikai

bk−i

=∑i=

0kci

k(∑a

i)(∑

bk−i

)=∑i

=0kk

!i!(

k−i)

!(∑a

i)(∑

bk−i

)=k!

∑i=0

k∑ai

i!∑b

k−i(

k−i)

! ∑(a

+b)k

=∑∑i

=0kc

kiai

bk−i

=∑i=

0kck

i(∑a

i)(∑

bk−i

)=∑i

=0kk

!i!(

k−i)

!(∑a

i)(∑

bk−i

)=k!

∑i=0

k∑ai

i!∑b

k−i(

k−i)

!這樣就是很明顯的卷積的形式了。

現在考慮怎麼計算∑a

i ∑a

i, 構造g(

x)=∏

ni=1

(1+a

ix) g(x

)=∏i

=1n(

1+ai

x)

然後對於g(

x)g (x

)求l

n ln

,再給第i i

項乘上i

' role="presentation">i

i就好了。

為什麼?

因為是乘積的形式,所以ln

l

n之後等價於對於所有東西都先ln

l

n在求和

所以考慮一下單個的ln

l

n值是什麼,然後有ln

′(a(

x))=

a′(x

)a(x

) ln′(

a(x)

)=a′

(x)a

(x

)這個手動用生成函式玩一下就知道了為啥了。

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

#define ll long long

#define rg register

#define mod 998244353

#define max 888888

inline

int read()

int fpow(int a,int b)

return s;

}int r[max],w[max];

void ntt(int *p,int len,int opt)

}if(opt==-1)

}int n,m,t[max];

int s1[max],s2[max];

int inv[max];

int f[max],p[max];

int jc[max],jcinv[max];

int tmp[50][max],st[50],top;

void solve(int l,int r,int *p,int *t)

int mid=(l+r)>>1,n,ls=st[top--];

solve(l,mid,tmp[ls],t);

int rs=st[top--];

solve(mid+1,r,tmp[rs],t);

for(n=1;n<=r-l+1;n<<=1);

ntt(tmp[ls],n,1);ntt(tmp[rs],n,1);

for(int i=0;i1ll*tmp[ls][i]*tmp[rs][i]%mod;

ntt(p,n,-1);

st[++top]=ls;st[++top]=rs;

for(int i=0;i0;

}namespace poly

inv(a,b,len>>1);

for(int i=0;i1,1);ntt(b,len<<1,1);

for(int i=0;i1;++i)a[i]=1ll*a[i]*b[i]%mod*b[i]%mod;

ntt(a,len<<1,-1);

for(int i=0;ifor(int i=0;ifor(int i=0;i1;++i)a[i]=b[i]=0;

}void dao(int *a,int *b,int len)

void jifen(int *a,int *b,int len)

int c[max],d[max];

void ln(int *a,int *b,int len)

int e[max],g[max];

void exp(int *a,int *b,int len)

exp(a,b,len>>1);ln(b,e,len);

for(int i=0;i0]=(e[0]+1)%mod;

for(int i=0;i1,1);ntt(g,len<<1,1);

for(int i=0;i1;++i)e[i]=1ll*e[i]*g[i]%mod;

ntt(e,len<<1,-1);

for(int i=0;ifor(int i=0;i1;++i)e[i]=g[i]=0;

}}int a[max],b[max],k;

int sa[max],sb[max];

int main()

return

0;}

洛谷5月月賽

n堆石子,每次可以從第i堆中取走乙個當且僅當ni ni 1 第0堆視作0個 拿不了就輸了。問先手贏還是後手贏。奇偶性問題。不管如何分布,必定全部被拿完。include inline char gc return s inline int read while c 0 c 9 return x f i...

洛谷 9月月賽

題目描述 眾所周知,在一些特殊的部門,如果密碼能夠讓乙個人就解開,就會非常不安全。pic pre invoked code,預生成密碼 誕生了。這個密碼比較安全,是因為它必須由三個人保管。系統首先預先生成三個大整數a b c,計算出它們的與and 或or 和sum並儲存,然後將a b c分別告訴這三...

洛谷10月月賽II

這道題考了矩陣旋轉 其實很考驗推公式的能力和 能力 這裡有個小技巧 可以設 x,y 為原點,然後去推公式,然後實際操作中橫座標加上x,縱座標加上y就好了。順時針 i,j j,i 逆時針 i,j j,i include define rep i,a,b for register int i a i b...