日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CF438E:The Child and Binary Tree(生成函数)

發布時間:2023/12/3 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CF438E:The Child and Binary Tree(生成函数) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

解析:

設計 fif_ifi? 表示權值為 iii 的方案數,f0=1f_0=1f0?=1
枚舉根節點權值,可以寫出轉移:
fn=∑gk∑ififn?k?i=∑i+j+k=nfifjgkf_n=\sum g_k\sum_{i}f_if_{n-k-i}=\sum_{i+j+k=n}f_if_jg_kfn?=gk?i?fi?fn?k?i?=i+j+k=n?fi?fj?gk?
其中 gk=1g_k=1gk?=1 表示集合中有元素 kkkgk=1g_k=1gk?=1 表示沒有元素 kkk

設它們的生成函數為 FFFGGG,就有:
F=GF2+1F=GF^2+1F=GF2+1
由于 GGG 的零次項為 000,無法求逆,考慮配方移項:
G2F2?GF+G=0G^2F^2-GF+G=0G2F2?GF+G=0
(GF?12)2=14?G(GF-\frac{1}{2})^2=\frac{1}{4}-G(GF?21?)2=41??G
GF=±14?G+12GF=±\sqrt{\frac{1}{4}-G}+\frac{1}{2}GF=±41??G?+21?
注意到,GFGFGF 的零次項應該為 000,而當右邊取正號時,零次項為 111,所以應該取負。
GF=?14?G+12=2G1+1?4GGF=-\sqrt{\frac{1}{4}-G}+\frac{1}{2}=\frac{2G}{1+\sqrt{1-4G}}GF=?41??G?+21?=1+1?4G?2G?
沒有逆,不能除下去,那我們就移過來:
G(F?(2G1+1?4G))=0G(F-(\frac{2G}{1+\sqrt{1-4G}}))=0G(F?(1+1?4G?2G?))=0
由于 GGG 系數不全為0,所以就有:
F=2G1+1?4GF=\frac{2G}{1+\sqrt{1-4G}}F=1+1?4G?2G?
上多項式開根和求逆即可。

#include<bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define debug(...) fprintf(stderr,__VA_ARGS__) inline ll read() {ll x(0),f(1);char c=getchar();while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f; } const int N=4e5+100; const int mod=998244353; int n,m,k; inline ll ksm(ll x,ll k){ll res=1;while(k){if(k&1) res=res*x%mod;x=x*x%mod;k>>=1;}return res; } int niv2=ksm(2,mod-2); int r[N]; void init(int n,int &lim){lim=1;int L=0;while(lim<n) lim<<=1,L++;for(int i=1;i<lim;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(L-1)); } void NTT(ll *x,int lim,int op){for(int i=0;i<lim;i++) if(i<r[i]) swap(x[i],x[r[i]]);for(int l=1;l<lim;l<<=1){ll w=ksm(3,(mod-1)/(l<<1));if(op==-1) w=ksm(w,mod-2);for(int st=0;st<lim;st+=(l<<1)){for(ll i=0,now=1;i<l;i++,now=now*w%mod){ll u=x[st+i],v=now*x[st+i+l]%mod;x[st+i]=u+v>=mod?u+v-mod:u+v;x[st+i+l]=u-v<0?u-v+mod:u-v;}}}if(op==-1){ll ni=ksm(lim,mod-2);for(int i=0;i<lim;i++) x[i]=x[i]*ni%mod;}return; } void copy(ll *a,ll *b,int n,int lim){assert(n<=lim);memcpy(a,b,sizeof(ll)*n);fill(a+n,a+lim,0);return; } void mul(ll *a,ll *b,ll *c,int n,int m){static ll u[N],v[N];static int lim;//for(int i=0;i<n;i++) printf("%lld ",a[i]);putchar('\n');//for(int i=0;i<m;i++) printf("%lld ",b[i]);putchar('\n');init(n+m-1,lim);copy(u,a,n,lim);copy(v,b,m,lim);NTT(u,lim,1);NTT(v,lim,1);for(int i=0;i<lim;i++) c[i]=u[i]*v[i]%mod;NTT(c,lim,-1);//for(int i=0;i<n+m-1;i++) printf("%lld ",c[i]);putchar('\n');//putchar('\n');return; } void inv(ll *h,ll *f,int n){static ll t1[N],t2[N];static int lim;if(n==1){f[0]=ksm(h[0],mod-2);return;}inv(h,f,(n+1)>>1);init(n<<1,lim);fill(f+((n+1)>>1),f+lim,0);copy(t1,f,n,lim);copy(t2,h,n,lim);NTT(t1,lim,1);NTT(t2,lim,1);for(int i=0;i<lim;i++) t1[i]=(2*t1[i]-t1[i]*t1[i]%mod*t2[i]%mod+mod)%mod;NTT(t1,lim,-1);memcpy(f,t1,sizeof(ll)*n);return; } //499122177 void Sqrt(ll *h,ll *f,int n){static ll t1[N],t2[N];static int lim;if(n==1){f[0]=1;return;}Sqrt(h,f,(n+1)>>1);init(n<<1,lim);fill(f+((n+1)>>1),f+lim,0);inv(f,t1,n);fill(t1+n,t1+lim,0);mul(h,t1,t1,n,n);copy(t2,f,n,lim);NTT(t1,lim,1);NTT(t2,lim,1);for(int i=0;i<lim;i++) t1[i]=(t1[i]+t2[i])*niv2%mod;NTT(t1,lim,-1);memcpy(f,t1,sizeof(ll)*n);return; } void dao(ll *h,ll *f,int n){static ll t[N];static int lim;init(n<<1,lim);copy(t,h,n,lim);f[n-1]=0;for(int i=0;i<n-1;i++) f[i]=t[i+1]*(i+1)%mod;fill(f+n,f+lim,0);return; } void jifen(ll *h,ll *f,int n){static ll t[N];static int lim;init(n<<1,lim);copy(t,h,n,lim);f[0]=0;for(int i=1;i<n;i++) f[i]=h[i-1]*ksm(i,mod-2)%mod;fill(f+n,f+lim,0); } void Ln(ll *h,ll *f,int n){static ll t1[N],t2[N];static int lim;init(n<<1,lim);inv(h,t1,n);fill(t1+n,t1+lim,0);dao(h,t2,n);mul(t1,t2,t1,n,n);jifen(t1,f,n);return; } void Exp(ll *h,ll *f,int n){static ll t1[N],t2[N],t3[N];static int lim;if(n==1){f[0]=1;return;}Exp(h,f,(n+1)>>1);init(n<<1,lim);fill(f+((n+1)>>1),f+lim,0);copy(t1,f,n,lim);copy(t2,h,n,lim);Ln(f,t3,n);fill(t3+n,t3+lim,0);NTT(t1,lim,1);NTT(t2,lim,1);NTT(t3,lim,1);for(int i=0;i<lim;i++) t1[i]=t1[i]*(1+t2[i]-t3[i]+mod)%mod;NTT(t1,lim,-1);memcpy(f,t1,sizeof(ll)*n);return; } void solve(ll *h,ll *w,ll *f,int l,int r){static ll t1[N],t2[N];static int lim;if(l==r) return;int mid=(l+r)>>1;solve(h,w,f,l,mid);int n=(r-l+1),m=(mid-l+1);init(n<<1,lim);copy(t1,h,n,lim);copy(t2,f+l,m,lim);//printf("\n(%d %d)\n",l,r);//for(int i=0;i<lim;i++) printf("%lld ",t1[i]);putchar('\n');//for(int i=0;i<lim;i++) printf("%lld ",t2[i]);putchar('\n');mul(t1,t2,t1,n,m);for(int i=1;i<=m;i++) (w[mid+i]+=2*t1[i])%=mod;copy(t1,w,n,lim);copy(t2,f+l,m,lim);mul(t1,t2,t1,n,m);for(int i=1;i<=m;i++) (f[mid+i]+=2*t1[i])%=mod;solve(h,w,f,mid+1,r);return; } ll a[N],b[N],c[N]; signed main() { #ifndef ONLINE_JUDGE//freopen("a.in","r",stdin);//freopen("a.out","w",stdout); #endifn=read();m=read();for(int i=1;i<=n;i++) a[read()]=1; n=m+1;int lim;init(n<<1,lim);for(int i=0;i<n;i++) a[i]=(mod-4*a[i])%mod;a[0]=(a[0]+1)%mod;Sqrt(a,b,n);b[0]=(b[0]+1)%mod;inv(b,c,n);for(int i=0;i<n;i++) c[i]=(c[i]<<1)%mod;for(int i=1;i<=m;i++) printf("%lld\n",c[i]);return 0; } /**/

總結

以上是生活随笔為你收集整理的CF438E:The Child and Binary Tree(生成函数)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。