题目描述

刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了.
刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得整个国家的任意两个城市都直接或间接的连通.
为了省钱, 每两个城市之间最多只能有一条直接的贸易路径. 对于两个建立路线的方案, 如果存在一个城市对, 在两个方案中是否建立路线不一样, 那么这两个方案就是不同的, 否则就是相同的. 现在你需要求出一共有多少不同的方案.
好了, 这就是困扰阿狸的问题. 换句话说, 你需要求出n个点的简单(无重边无自环)无向连通图数目.
由于这个数字可能非常大, 你只需要输出方案数mod 1004535809(479 * 2 ^ 21 + 1)即可.

题解

其实就是无向连通图计数问题。

都给了这个模数了,肯定要FFT做。

考虑定义生成函数F表示n个点的连通图个数。

G表示n个点的无向图个数,各一发现,G[i]=2C(n,2)

然后考虑dp出G来。

G[n]=∑F[i]*G[n-i]*C(n-1,i-1)

这里的i枚举的是和1点连通的点的个数。

然后看到组合数就得想一想怎么把它拆开。

G[n]=∑F[i]*G[n-i]*(n-1)!*(1/(i-1)!)*(1/(n-i)!)

把右边的(n-1)!移到左边去。

G[n]/(n-1)!=∑F[i]/(i-1)!*G[n-i]/(n-i)!

于是这个式子变成可卷积的形式。

那么我们令

C=F[i]/(i-1)!  

Q=2C(n,2)/n!

Q'=2C(n,2)/(n-1)!

那么Q'=Q*C

C=Q*Q'-1

求一个逆就好了。

注意:当我们预处理多项式的时候,遇到一些奇怪的式子的时候,要想一想它的实际意义。

例如G[0]表示0个点的答案显然为1,G[1]同理也是1,但按照式子算的话为0,这时应从实际的角度计算。

C[0]中有一项为(-1)!但是并没有找到什么和实际有关的,所以我们认为这一项为0。

代码

#include<iostream>
#include<cstdio>
#define N 550002
using namespace std;
typedef long long ll;
ll g[N],a[N],b[N],rev[N],c[N],n,jie[N],ni[N],yu[N];
const ll mod=;
const ll G=;
const ll Gi=;
inline int rd(){
int x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
inline ll power(ll x,ll y){
ll ans=;
while(y){if(y&)ans=ans*x%mod;x=x*x%mod;y>>=;}
return ans;
}
inline void NTT(ll *a,int l,int tag){
for(int i=;i<l;++i)if(i>rev[i])swap(a[i],a[rev[i]]);
for(int i=;i<l;i<<=){
ll wn=power(tag==?G:Gi,(mod-)/(i<<));
for(int j=;j<l;j+=(i<<)){
ll w=;
for(int k=;k<i;++k,w=w*wn%mod){
ll x=a[j+k],y=a[i+j+k]*w%mod;
a[j+k]=(x+y)%mod;;a[i+j+k]=(x-y+mod)%mod;
}
}
}
}
inline void inv(int n){
if(n==){b[]=power(g[],mod-);return;}
inv((n+)>>);
int l=,L=;
while(l<=(n<<))l<<=,L++;
for(int i=;i<l;++i)rev[i]=(rev[i>>]>>)|((i&)<<(L-));
for(int i=;i<n;++i)a[i]=g[i];
for(int i=n;i<l;++i)a[i]=;
NTT(a,l,);NTT(b,l,);
for(int i=;i<l;++i)b[i]=(2ll-a[i]*b[i]%mod+mod)%mod*b[i]%mod;
NTT(b,l,-);ll ny=power(l,mod-);
for(int i=;i<n;++i)b[i]=b[i]*ny%mod;
for(int i=n;i<l;++i)b[i]=;
}
inline ll C(ll n){return n*(n-)/;}
int main(){
n=rd();
jie[]=;
for(int i=;i<=n;++i)jie[i]=jie[i-]*i%mod;ni[n]=power(jie[n],mod-);
for(int i=n-;i>=;--i)ni[i]=ni[i+]*(i+)%mod;
yu[]=yu[]=;
for(int i=;i<=n;++i)yu[i]=power(,C(i));
g[]=yu[]*ni[]%mod;
for(int i=;i<=n;++i){
c[i]=yu[i]*ni[i-]%mod;
g[i]=yu[i]*ni[i]%mod;
}
// for(int i=0;i<=n;++i)cout<<c[i]<<" ";puts("");
// for(int i=0;i<=n;++i)cout<<g[i]<<" ";puts("");
inv(n+);
int l=,L=;
while(l<=(n<<))l<<=,L++;
for(int i=;i<l;++i)rev[i]=(rev[i>>]>>)|((i&)<<(L-));
// for(int i=0;i<l;++i)cout<<b[i]<<" ";cout<<endl;
NTT(c,l,);NTT(b,l,);
for(int i=;i<l;++i)c[i]=c[i]*b[i]%mod;
NTT(c,l,-);ll ny=power(l,mod-);
for(int i=;i<l;++i)c[i]=c[i]*ny%mod;
cout<<c[n]*jie[n-]%mod;
return ;
}

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. BZOJ3456 城市规划 【分治NTT】

    题目链接 BZOJ3456 题解 据说这题是多项式求逆 我太弱不会QAQ,只能\(O(nlog^2n)\)分治\(NTT\) 设\(f[i]\)表示\(i\)个节点的简单无向连通图的数量 考虑转移,直 ...

  6. BZOJ3456: 城市规划

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

  7. BZOJ3456 城市规划 【生成函数】【FFT】

    题目分析: 容易想到生成函数的构造方法. 令g(n)表示n个点的无向图个数,f(n)表示n个点的无向连通图的个数.式子是显然的. 容易发现式子是卷积的形式,写出生成函数,然后多项式求逆后多项式乘法即可 ...

  8. 2019.01.03 bzoj3456: 城市规划(生成函数+多项式取对)

    传送门 生成函数好题. 题意:求n个点的简单(无重边无自环)无向连通图数目 思路: 对简单无向图构造生成函数f(x)=∑n2Cn2xnn!f(x)=\sum_n2^{C_n^2}\frac{x^n}{ ...

  9. bzoj3456 城市规划 多项式求In

    \(n\)个点的无向联通图的个数 打着好累啊 一定要封装一个板子 记\(C(x)\)为无向图个数的指数型生成函数,\(C(0) = 1\) 记\(G(x)\)为无向联通图个数的指数型生成函数,\(G( ...

随机推荐

  1. 设置抓包工具Fiddler的host

    大家都知道在电脑本地上有一个Host文件. Hosts文件主要作用是定义IP地址和主机名的映射关系,是一个映射IP地址和主机名的规定.可以用文本文件打开!当用户在浏览器中输入一个需要登录的网址时,系统 ...

  2. gitbook 入门教程之常用命令详解

    不论是 gitbook-cli 命令行还是 gitbook editor 编辑器都离不开 gitbook 命令的操作使用,所以再次了解下常用命令. 注意 gitbook-cli 是 gitbook 的 ...

  3. github、git软件安装、pycharm下使用git配置、git GUI相关

    1.GitHub: 官网:直接搜索,排名很靠前,需要注册: 注册完之后,会有指引.新建项目两个选项(看不懂的问YOUDAO等翻译软件啦,大段复制进去就行) 2.Git安装: (https://git- ...

  4. DataReader的使用

    public List<Student> GetList()        {            string sql = "select * from Student&qu ...

  5. Oracle 12c用户和安全管理

    前言: Oracle 12c的多租户(multitenant)环境与SQL Server的架构非常相似,CDB$ROOT类似于master.PDB$SEED类似于model.各个pluggable d ...

  6. luajit官方性能优化指南和注解

    luajit是目前最快的脚本语言之一,不过深入使用就很快会发现,要把这个语言用到像宣称那样高性能,并不是那么容易.实际使用的时候往往会发现,刚开始写的一些小test case性能非常好,经常毫秒级就算 ...

  7. python3 str(字符串)

    __add__函数 (在后面追加字符串) s1 ='Hello' s2 = s1.__add__(' boy!') print(s2) #输出:Hello boy! __contains__(判断是否 ...

  8. SQLServer之创建辅助XML索引

    创建辅助XML索引 使用 CREATE INDEX (Transact-SQL)Transact-SQL DDL 语句可创建辅助 XML 索引并且可指定所需的辅助 XML 索引的类型. 创建辅助 XM ...

  9. HBase案例:HBase 在人工智能场景的使用

    近几年来,人工智能逐渐火热起来,特别是和大数据一起结合使用.人工智能的主要场景又包括图像能力.语音能力.自然语言处理能力和用户画像能力等等.这些场景我们都需要处理海量的数据,处理完的数据一般都需要存储 ...

  10. c# 小数四舍五入,向上取整,向下取整,见角进元保留多个小数位数

    /// <summary> /// 实现数据的四舍五入法 /// </summary> /// <param name="v">要进行处理的数据 ...