Noi2016十连测第二场-黑暗 (二项式定理/斯特林数+CDQ+NTT)

Noi2016十连测第二场-黑暗 (二项式定理/斯特林数+CDQ+NTT)

题意: n 个点的无向图,每条边都可能存在,一个图的权值是连通块个数的 m 次方,求所有可能的图的权值和。

考虑\(dp[i][j]\)表示\(j\)个点,权值为\(i\)次方

我们首先要预处理出\(n\)个点无向联通图的数量\(g[i]\),模板题:BZOJ-3456 题解

对于\(dp[i][j]\),枚举\(1\)号点所在的连通块大小为\(x\),那么可以得到的是\(dp[i][j]=\sum dp[k][j-x]\cdot C(j-1,x-1)\cdot C(i,k)\cdot g[x]\)(每次转移一个连通块,用二项式定理展开来求次方)

利用\(CDQ+NTT\)可以完成转移,模板题:HDU-5730 题解

#include
using namespace std;

//#define int long long

#define reg register
typedef long long ll;
#define rep(i,a,b) for(reg int i=a,i##end=b;i<=i##end;++i)
#define drep(i,a,b) for(reg int i=a,i##end=b;i>=i##end;--i)
#define Mod2(x) ((x<0)&&(x+=P))
#define Mod1(x) ((x>=P)&&(x-=P))

template  inline void cmin(T &a,T b){ ((a>b)&&(a=b)); }
template  inline void cmax(T &a,T b){ ((a>=1,x=x*x%P) if(k&1) res=res*x%P;
    return res;
}

int g[N],h[N],dp[16][N],w[N];
int A[16][N],B[N];
int rev[N];
void NTT(int n,int *a,int f) {
    rep(i,1,n-1) if(i>1;
    Solve1(l,mid);
    int R=1,cc=-1;
    while(R<=r-l+1) R<<=1,cc++;
    rep(i,1,R) rev[i]=(rev[i>>1]>>1)|((i&1)<>1;
    Solve(l,mid);
    int R=1,cc=-1;
    while(R<=r-l+1) R<<=1,cc++;
    rep(i,1,R) rev[i]=(rev[i>>1]>>1)|((i&1)<

你可能感兴趣的:(Noi2016十连测第二场-黑暗 (二项式定理/斯特林数+CDQ+NTT))