[第二类斯特林数 组合计数] 省选模拟赛 2 B. 两弹一星 missile
2017-03-18 21:01
429 查看
题目大意
一张无向图的权值定义为 xk,其中 x 是图中结构为树的连通块个数。给定 n, k, 求出所有 n 个点带标号的的简单无向图的权值和,对 998244353 取模。
令 xi 表示树联通块 i 是否存在 , 图的权值为 (∑xi)m。对于某 k 个联通块,如果同时出现,那么贡献为 S(m,k)∗k!
令 fn 为 n个点的树连通图个数,直接由prufer得出
令 gi,j 为 i 个点 j 个树连通块的个数,通过简单 dp 求得
再将求出来的东西套入之前的斯特林数式子就可以计算答案
dp用FFT 来优化
一张无向图的权值定义为 xk,其中 x 是图中结构为树的连通块个数。给定 n, k, 求出所有 n 个点带标号的的简单无向图的权值和,对 998244353 取模。
令 xi 表示树联通块 i 是否存在 , 图的权值为 (∑xi)m。对于某 k 个联通块,如果同时出现,那么贡献为 S(m,k)∗k!
令 fn 为 n个点的树连通图个数,直接由prufer得出
令 gi,j 为 i 个点 j 个树连通块的个数,通过简单 dp 求得
再将求出来的东西套入之前的斯特林数式子就可以计算答案
dp用FFT 来优化
#include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; typedef long long ll; const int N=200005; const int P=998244353; const int G=3; inline ll Pow(ll a,int b){ ll ret=1; for (;b;b>>=1,a=a*a%P) if (b&1) ret=ret*a%P; return ret; } int num; int w[2] ; int R ; inline void Init(int n){ int x=n,L=0; num=n; while (n>>=1) L++; for (int i=1;i<num;i++) R[i]=(R[i>>1]>>1)|((i&1)<<(L-1)); ll g=Pow(G,(P-1)/num); w[1][0]=w[0][0]=1; for (int i=1;i<num;i++) w[1][i]=(ll)w[1][i-1]*g%P; for (int i=1;i<num;i++) w[0][i]=w[1][num-i]; } inline void FFT(int *a,int n,int r){ for (int i=0;i<n;i++) if (i<R[i]) swap(a[i],a[R[i]]); for (int i=1;i<n;i<<=1) for (int j=0;j<n;j+=(i<<1)) for (int k=0;k<i;k++){ ll x=a[j+k],y=(ll)w[r][num/(i<<1)*k]*a[j+i+k]%P; a[j+k]=(x+y)%P; a[j+i+k]=(x+P-y)%P; } if (!r) for (int i=0,inv=Pow(n,P-2);i<n;i++) a[i]=(ll)a[i]*inv%P; } ll fac ,inv ,S[25][25]; inline ll C(int n,int m){ if (n<m) return 0; return fac *inv[m]%P*inv[n-m]%P; } ll f ,g[25] ; inline void Pre(int n,int K){ fac[0]=1; for (int i=1;i<=n;i++) fac[i]=fac[i-1]*i%P; inv[1]=1; for (int i=2;i<=n;i++) inv[i]=(ll)(P-P/i)*inv[P%i]%P; inv[0]=1; for (int i=1;i<=n;i++) inv[i]=inv[i]*inv[i-1]%P; f[1]=1; for (int i=2;i<=n;i++) f[i]=Pow(i,i-2); S[0][0]=1; for (int i=1;i<=K;i++){ S[i][0]=0; for (int j=1;j<=i;j++) S[i][j]=(S[i-1][j-1]+(ll)S[i-1][j]*j%P)%P; } } int n,K; ll Ans; int m; int A ,B ; inline void Calc_G(ll *ng,ll *g){ for (int i=0;i<m;i++) A[i]=B[i]=0; for (int i=0;i<=n;i++) A[i]=(ll)g[i]*inv[i]%P; for (int i=1;i<=n;i++) B[i]=(ll)f[i]*inv[i-1]%P; FFT(A,m,1); FFT(B,m,1); for (int i=0;i<m;i++) A[i]=(ll)A[i]*B[i]%P; FFT(A,m,0); for (int i=1;i<=n;i++) ng[i]=(ll)A[i]*fac[i-1]%P; } int main(){ freopen("missile.in","r",stdin); freopen("missile.out","w",stdout); scanf("%d%d",&n,&K); Pre(n,K); for (m=1;m<=(n<<1);m<<=1); Init(m); g[0][0]=1; for (int j=1;j<=K;j++) Calc_G(g[j],g[j-1]); Ans=0; for (int i=1;i<=n;i++) for (int j=1;j<=K;j++) (Ans+=g[j][i]*C(n,i)%P*Pow(2,C(n-i,2))%P*S[K][j]%P*fac[j]%P)%=P; printf("%d\n",Ans); return 0; }
相关文章推荐
- poj3252(排列组合计数,数位计数)
- 组合计数总结(转)
- BZOJ 1801: [Ahoi2009]chess 中国象棋 [DP 组合计数]
- ZOJ-3380 Patchouli’s Spell Cards DP, 组合计数
- 排列组合计数 水poj2249 poj1306
- POJ 2282-The Counting Problem(组合数学_区间计数)
- 2017.04.15【NOIP2017提高组】模拟赛B组 T3:菱形内的计数
- BZOJ3209 花神的数论题 【组合数 + 按位计数】
- uva 11038 How Many O's? 组合计数
- HDU 3723 Delta Wave(组合计数,卡特兰数)
- 组合计数总结(转)
- BZOJ 2111: [ZJOI2010]Perm 排列计数|组合数学|Lucas定理|DP
- [bzoj4517][Sdoi2016]排列计数(组合数学)
- 4000 【Java】计蒜客 蓝桥杯模拟赛5 组合数字
- hdu1510 White Rectangles(组合计数问题)
- [仙人掌 并查集 组合计数] BZOJ 4450 [Neerc2015]Cactus Jubilee
- BZOJ 4517: [Sdoi2016]排列计数 组合数 错排公式
- [Codeforces Round #369 (Div. 2)D. Directed Roads]Tarjan强连通分量+组合计数
- [ACM] ZOJ 3725 Painting Storages (DP计数+组合)
- 2014.8.2模拟赛【果实计数】