【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. (转)Syntax error:

    但是运行时总是报下面这个错,如下: test11-loop.sh: 5: Syntax error: Bad for loop variable 几经查找语法,没有问题,后来在网上找到问题原因: 代码 ...

  2. Python高阶函数--map

    map()函数 map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把list 的每个元素依次作用在函数 f 上,得到一个新的 list 并返回. 例如,对于lis ...

  3. python3通过gevent.pool限制协程并发数量

    协程虽然是轻量级的线程,但到达一定数量后,仍然会造成服务器崩溃出错.最好的方法通过限制协程并发数量来解决此类问题. server代码: #!/usr/bin/env python # -*- codi ...

  4. 记一次MongoDB裸奔

    导言 大意失荆州,裸奔的 MongoDB 被黑了.虽然并不是什么非常重要的数据,但也给自己敲响的一个警钟.虽然我们平时不容易接触到数据安全,但我们在开发,部署项目的时候,一定要养成良好的安全意识. 根 ...

  5. python基础学习笔记(二)

    继续第一篇的内容,讲解,python的一些基本的东西. 注释 为了让别人能够更容易理解程序,使用注释是非常有效的,即使是自己回头再看旧代码也是一样. >>> #获得用户名: > ...

  6. QQ使用的使用评价

    1:界面以及功能:打开软件之后探出登录窗口,基本功能的登录,找回密码,注册帐号等功能均在比较醒目的位置,界面较为友好. 将注册帐号放在打开软件的第一界面当然是正确的选择,给予用户非常直观的提示(没有帐 ...

  7. 12.12 Daily Scrum

    这周末我们会集成一下反馈活跃用户的模块. 另外,今天编译的第一次测试结束,周末这两天项目的进度会比之前加快一些.   Today's Task Tomorrow's Task 丁辛 实现和菜谱相关的餐 ...

  8. 【CV】ICCV2015_Unsupervised Learning of Visual Representations using Videos

    Unsupervised Learning of Visual Representations using Videos Note here: it's a learning note on Prof ...

  9. 《面向对象程序设计》c++第五次作业___calculator plus plus

    c++第五次作业 Calculator plusplus 代码传送门 PS:这次作业仍然orz感谢一位同学与一位学长的windows帮助,同时再次吐槽作业对Mac系统用户的不友好.(没朋友千万别用Ma ...

  10. “数学口袋精灵”App的第三个Sprint计划(总结与团队感悟)----开发日记

    第三阶段Sprint完成情况: 我们的"数学口袋精灵"App已经完成了,该app能随机产生多种形式的算式,比如带括号的,分数四则运算,混合运算,阶乘等,通过游戏形式让用户乐在其中. ...