【BZOJ3456】城市规划(生成函数,多项式运算)

题面

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

\(n<=130000\)

题解

\(n\)个点的无向图的个数\(g(n)=2^{C_n^2}\)。设\(n\)个点的无向连通图个数为\(f(n)\)。有等式:

\[g(n)=\sum_{i=1}^{n}C_{n-1}^{i-1}f(i)g(n-i)
\]

即考虑枚举\(1\)号点所在联通块的点。

将\(g(n)\)带入式子

\[2^{C_n^2}=\sum_{i=1}^{n}C_{n-1}^{i-1}f(i)2^{C_{n-i}^2}
\]

将组合数拆开后,两侧除掉只与\(n\)有关的\((n-1)!\)

\[\frac{2^{C_n^2}}{(n-1)!}=\sum_{i=1}^{n}\frac{f(i)}{(i-1)!}\frac{2^{C_{n-i}^2}}{(n-i)!}
\]

构造生成函数\(F(x)=\sum_{i=1}^{\infty}\frac{f(i)}{(i-1)!}x^i\),\(G(x)=\sum_{i=0}^{\infty}\frac{g(i)}{i!}x^i\),\(C(x)=\sum_{i=1}^{\infty}\frac{g(i)}{(i-1)!}x^i\)。

然后有式子\(C(x)=F(x)G(x)\)。\(F(x)=C(x)G^{-1}(x)\)。

多项式求逆即可,时间复杂度\(O(nlogn)\)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 333333
const int MOD=1004535809;
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int n,inv[MAX],jc[MAX],jv[MAX],p[MAX];
int fpow(int a,int b)
{
int s=1;
while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}
return s;
}
int r[MAX],W[MAX];
void NTT(int *P,int len,int opt)
{
int N,l=0;for(N=1;N<len;N<<=1)++l;
for(int i=1;i<N;++i)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
for(int i=1;i<N;++i)if(i<r[i])swap(P[i],P[r[i]]);
for(int i=1;i<N;i<<=1)
{
int w=fpow(3,(MOD-1)/(i<<1));W[0]=1;
for(int k=1;k<i;++k)W[k]=1ll*W[k-1]*w%MOD;
for(int p=i<<1,j=0;j<N;j+=p)
for(int k=0;k<i;++k)
{
int X=P[j+k],Y=1ll*W[k]*P[i+j+k]%MOD;
P[j+k]=(X+Y)%MOD;P[i+j+k]=(X+MOD-Y)%MOD;
}
}
if(opt==-1)
{
reverse(&P[1],&P[N]);
for(int i=0,inv=fpow(N,MOD-2);i<N;++i)P[i]=1ll*P[i]*inv%MOD;
}
}
int A[MAX],B[MAX];
void Inv(int *a,int *b,int len)
{
if(len==1){b[0]=fpow(a[0],MOD-2);return;}
Inv(a,b,len>>1);
for(int i=0;i<len;++i)A[i]=a[i],B[i]=b[i];
NTT(A,len<<1,1);NTT(B,len<<1,1);
for(int i=0;i<(len<<1);++i)A[i]=1ll*A[i]*B[i]%MOD*B[i]%MOD;
NTT(A,len<<1,-1);
for(int i=0;i<len;++i)b[i]=((b[i]+b[i])%MOD+MOD-A[i])%MOD;
for(int i=0;i<(len<<1);++i)A[i]=B[i]=0;
}
int C[MAX],G[MAX],D[MAX],F[MAX];
int main()
{
n=read();
int N;for(N=1;N<=n;N<<=1);
inv[0]=jc[0]=inv[1]=jc[1]=jv[0]=jv[1]=1;
for(int i=2;i<=n;++i)
{
jc[i]=1ll*jc[i-1]*i%MOD;
inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
jv[i]=1ll*jv[i-1]*inv[i]%MOD;
}
p[0]=p[1]=1;
for(int i=2;i<=n;++i)p[i]=fpow(2,1ll*i*(i-1)/2%(MOD-1));
for(int i=0;i<=n;++i)G[i]=1ll*p[i]*jv[i]%MOD;
for(int i=1;i<=n;++i)C[i]=1ll*p[i]*jv[i-1]%MOD;
Inv(G,D,N);
NTT(D,N,1);NTT(C,N,1);
for(int i=0;i<N;++i)F[i]=1ll*D[i]*C[i]%MOD;
NTT(F,N,-1);
printf("%lld\n",1ll*F[n]*jc[n-1]%MOD);
return 0;
}

【BZOJ3456】城市规划(生成函数,多项式运算)的更多相关文章

  1. [BZOJ3456]城市规划(生成函数+多项式求逆+多项式求ln)

    城市规划 时间限制:40s      空间限制:256MB 题目描述 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了.  刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一 ...

  2. BZOJ3456 城市规划 【多项式求ln】

    题目链接 BZOJ3456 题解 真是一道经典好题,至此已经写了分治\(NTT\),多项式求逆,多项式求\(ln\)三种写法 我们发现我们要求的是大小为\(n\)无向联通图的数量 而\(n\)个点的无 ...

  3. BZOJ3456 城市规划(多项式求逆)

    设f[i]为连通图的数量,g[i]为不连通图的数量,显然有f[i]=2i*(i-1)/2-g[i],g[i]通过枚举1所在连通块大小转移,有g[i]=Σf[j]*C(i-1,j-1)·2(i-j)*( ...

  4. BZOJ3456 城市规划 【多项式求逆】

    题目链接 BZOJ3456 题解 之前我们用分治\(ntt\)在\(O(nlog^2n)\)的复杂度下做了这题,今天我们使用多项式求逆 设\(f_n\)表示\(n\)个点带标号无向连通图数 设\(g_ ...

  5. 洛谷P4841 城市规划(生成函数 多项式求逆)

    题意 链接 Sol Orz yyb 一开始想的是直接设\(f_i\)表示\(i\)个点的无向联通图个数,枚举最后一个联通块转移,发现有一种情况转移不到... 正解是先设\(g(n)\)表示\(n\)个 ...

  6. 洛谷P4705 玩游戏(生成函数+多项式运算)

    题面 传送门 题解 妈呀这辣鸡题目调了我整整三天--最后发现竟然是因为分治\(NTT\)之后的多项式长度不是\(2\)的幂导致把多项式的值存下来的时候发生了一些玄学错误--玄学到了我\(WA\)的点全 ...

  7. [bzoj3456]城市规划:多项式,分治

    Description 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了. 刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得整个国家的任意两个城市都直接或 ...

  8. 【CF438E】The Child and Binary Tree(多项式运算,生成函数)

    [CF438E]The Child and Binary Tree(多项式运算,生成函数) 题面 有一个大小为\(n\)的集合\(S\) 问所有点权都在集合中,并且点权之和分别为\([0,m]\)的二 ...

  9. 【BZOJ3771】Triple(生成函数,多项式运算)

    [BZOJ3771]Triple(生成函数,多项式运算) 题面 有\(n\)个价值\(w\)不同的物品 可以任意选择\(1,2,3\)个组合在一起 输出能够组成的所有价值以及方案数. \(n,w< ...

随机推荐

  1. React-页面路由参数传递的两种方法

    list页->detail页 方法一:路由参数 路由导航: 用“/” <Link to={'/detail/'+item.get('id')} key={index}> 路由map: ...

  2. AngularJs的ng-include的使用与实现

    想在angularjs动态加载一个内容,我们可以使用ng-include来实现. 今天Insus.NET就在ASP.NET MVC环境中,举个例子来演示它的功能. 你可以在一个视图动态加载任一其它视图 ...

  3. [Oracle]如何查看 10046 trace 中的 tim= ... 的具体时刻

    可以在  Linux 下,用下列方式: 如10046 trace 文件中如果有如下的内容:... tim = 1503032923 可以用 date 命令加 option 来看它的时刻: date - ...

  4. AtCoder ExaWizards 2019 简要题解

    AtCoder ExaWizards 2019 简要题解 Tags:题解 link:https://atcoder.jp/contests/exawizards2019 很水的一场ARC啊,随随便便就 ...

  5. Auto-ML之自动化特征工程

    1. 引言 个人以为,机器学习是朝着更高的易用性.更低的技术门槛.更敏捷的开发成本的方向去发展,且Auto-ML或者Auto-DL的发展无疑是最好的证明.因此花费一些时间学习了解了Auto-ML领域的 ...

  6. python语言程序设计3

    1, 起码坚持每天  半小时吧... 2, 上面有常用的几个数据类型..整数类型和字符串类型还行,但是列表类型的话就很蛋疼了. 3, 字符串类型的显著特点是在两侧有单引号或者双引号.用单引号和双引号表 ...

  7. Samba共享目录的多用户权限设置案例

    下面根据实际工作中遇到的一个共享目录的多用户权限需求案例来说明下Samba用户权限的设置. 一.需求场景领导:李一(liyi)正式员工(zhengshiyuangong):刘二二(liuerer).于 ...

  8. Redis常用操作-----字符串

    1.APPEND key value 如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾. 如果 key 不存在, APPEND 就简单地将给定 ...

  9. linux-shell-引用-命令替换-命令退出状态-逻辑操作符

    命令替换:bash7步扩展的之一 嵌套  这里没什么意义 退出状态可以参与逻辑判断 表达式 算数表达式和条件表达式,逻辑表达式 查看passwd命令比,避免用户捕获输入密码的接口 这种方式就可以直接输 ...

  10. C. Multiplicity

    链接 [http://codeforces.com/contest/1061/problem/C] 题意 给你一个数组,让你找有多少个子串(并非连续,但相对位置不能换),满足bi%i==0; 分析 d ...