zoukankan      html  css  js  c++  java
  • BZOJ3456 城市规划

    题面

    洛谷

    (mathrm{bzoj})权限题

    一句话题面

    (n)个点的无向连通图个数。

    (nleq 130000)

    题解

    首先我们知道,(n)个点的无向图个数为(mathrm{g}(n) = 2^{mathrm{C}_n^2})

    (n)个点的无向连通图的个数为(mathrm{f}(n))

    那么我们枚举(1)号点所在的连通块的大小(i),可以知道

    [mathrm{g}(n) = sum_{i=1}^n inom{n - 1}{i - 1} mathrm{f}(i)mathrm{g}(n-i) ]

    拆开组合数:

    [egin{aligned} mathrm{g}(n) &= sum_{i=1}^n frac{(n-1)!}{(i-1)!(n-i)!}mathrm{f}(i)mathrm{g}(n-i) \ frac{mathrm{g}(n)}{(n-1)!} &= sum_{i=1}^n frac{mathrm{f}(i)}{(i-1)!} frac{mathrm{g}(n-i)}{(n-i)!} end{aligned} ]

    构造生成函数:

    [egin{aligned} mathcal{F}(x) &= sum_{i=1}^infty frac{mathrm{f}(i)}{(i-1)!}x^i \ mathrm{G_1}(x) &= sum_{i=0}^infty frac{mathrm{g}(i)}{i!}x^i \ mathrm{G_2}(x) &= sum_{i=1}^infty frac{mathrm{g}(i)}{(i-1)!}x^i end{aligned} ]

    那么(mathrm{G_2} = mathcal{F}*mathrm{G_1}, mathcal{F} = mathrm{G_1} * mathrm{G_2^{-1}})

    多项式求逆即可

    代码

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #define RG register
    #define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
    #define clear(x, y) memset(x, y, sizeof(x))
    
    inline int read()
    {
    	int data = 0, w = 1; char ch = getchar();
    	while(ch != '-' && (!isdigit(ch))) ch = getchar();
    	if(ch == '-') w = -1, ch = getchar();
    	while(isdigit(ch)) data = data * 10 + (ch ^ 48), ch = getchar();
    	return data * w;
    }
    
    const int maxn(400010), Mod(1004535809);
    int n, fac[maxn], inv[maxn], Pow[maxn];
    
    int fastpow(int x, int y)
    {
    	int ans = 1;
    	while(y)
    	{
    		if(y & 1) ans = 1ll * ans * x % Mod;
    		x = 1ll * x * x % Mod, y >>= 1;
    	}
    	return ans;
    }
    
    int r[maxn];
    template<int opt> void FFT(int *p, int N)
    {
    	for(RG int i = 0; i < N; i++) if(i < r[i]) std::swap(p[i], p[r[i]]);
    	for(RG int i = 1; i < N; i <<= 1)
    	{
    		int rot = fastpow(3, (Mod - 1) / (i << 1));
    		for(RG int j = 0; j < N; j += (i << 1))
    			for(RG int k = 0, w = 1; k < i; ++k, w = 1ll * w * rot % Mod)
    			{
    				int x = p[j + k], y = 1ll * w * p[i + j + k] % Mod;
    				p[j + k] = (x + y) % Mod, p[i + j + k] = (x - y + Mod) % Mod;
    			}
    	}
    	if(opt == -1) std::reverse(p + 1, p + N);
    }
    
    void Inv(int *a, int *b, int now)
    {
    	static int c[maxn];
    	if(now == 1) return (void) (*b = fastpow(*a, Mod - 2));
    	Inv(a, b, (now + 1) >> 1); int P = -1, len = 1;
    	while(len < (now << 1)) len <<= 1, ++P;
    	for(RG int i = 0; i < len; i++) r[i] = (r[i >> 1] >> 1) | ((i & 1) << P);
    	std::copy(a, a + now, c), std::fill(c + now, c + len, 0);
    	FFT<1>(c, len), FFT<1>(b, len);
    	for(RG int i = 0; i < len; i++)
    		b[i] = 1ll * (2 - 1ll * b[i] * c[i] % Mod + Mod) % Mod * b[i] % Mod;
    	FFT<-1>(b, len); int invn = fastpow(len, Mod - 2);
    	for(RG int i = 0; i < len; i++) b[i] = 1ll * b[i] * invn % Mod;
    	std::fill(b + now, b + len, 0);
    }
    
    int F[maxn], G1[maxn], G2[maxn], A[maxn];
    int main()
    {
    #ifndef ONLINE_JUDGE
    	file(cpp);
    #endif
    	n = read(), inv[0] = fac[0] = Pow[0] = Pow[1] = 1;
    	for(RG int i = 1; i <= n; i++) fac[i] = 1ll * fac[i - 1] * i % Mod;
    	inv[n] = fastpow(fac[n], Mod - 2);
    	for(RG int i = n - 1; i; i--) inv[i] = 1ll * inv[i + 1] * (i + 1) % Mod;
    	for(RG int i = 2; i <= n; i++)
    		Pow[i] = fastpow(2, 1ll * i * (i - 1) / 2 % (Mod - 1));
    	for(RG int i = 0; i <= n; i++) G1[i] = 1ll * Pow[i] * inv[i] % Mod;
    	for(RG int i = 1; i <= n; i++) G2[i] = 1ll * Pow[i] * inv[i - 1] % Mod;
    	Inv(G1, A, n + 1); int N = 1, P = -1;
    	while(N <= (n << 1)) N <<= 1, ++P;
    	for(RG int i = 0; i < N; i++) r[i] = (r[i >> 1] >> 1) | ((i & 1) << P);
    	FFT<1>(A, N), FFT<1>(G2, N);
    	for(RG int i = 0; i < N; i++) F[i] = 1ll * A[i] * G2[i] % Mod;
    	FFT<-1>(F, N); int invn = fastpow(N, Mod - 2);
    	F[n] = 1ll * F[n] * invn % Mod;
    	printf("%lld
    ", 1ll * F[n] * fac[n - 1] % Mod);
    	return 0;
    }
    
  • 相关阅读:
    pandas Series和DataFrame数据类型
    numpy 统计函数与随机数
    numpy 索引
    numpy 数组复制与广播机制
    numpy 合并数组和切割数组
    numpy 添加删除去重及形状变换
    项目导入问题---讨厌的红色感叹号
    SpringMVC框架-----概述(2)
    SpringMVC框架-----概述(1)
    SpringBoot框架----概述(1)
  • 原文地址:https://www.cnblogs.com/cj-xxz/p/10337152.html
Copyright © 2011-2022 走看看