博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 3456: 城市规划 多项式求逆
阅读量:5275 次
发布时间:2019-06-14

本文共 2975 字,大约阅读时间需要 9 分钟。

Description

 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了.

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

Input

 仅一行一个整数n(<=130000)

Output

 仅一行一个整数, 为方案数 mod 1004535809.

 

题解:

 

多项式好有趣
 
我们先考虑递推式:
令 $f(n)$ 代表 $n$ 个点简单联通无向图个数.
令 $g(n)$ 代表 $n$ 个点无向图个数 (不要求联通).
不难求出,$g(n)=\frac{n(n-1)}{2}$,即 $\binom{n}{2}$.
然而,$f(n)$ 似乎特别难求.
枚举 $1$ 号点所在的联通块:
 
得 $g(n)=\sum_{i=1}^{n}\binom{n-1}{i-1}f(i)g(n-i)$
 
思考一下该公式代表的含义:
枚举 $1$ 号点所在的联通块大小,其余的点随便连,如何保证不会重复枚举?
每一次 $1$ 号点所在的联通块大小是固定的.
其余的点之间不能连到 $1$ 号点所在联通块中,这样就满足了要求.
 
把 $g(n)$ 带入, 得:
 
$2^{\binom{n}{2}}=\sum_{i=1}^{n}\binom{n-1}{i-1}f(i)2^{\binom{n-i}{2}}$
 
把组合数展开,得:
 
$2^{\binom{n}{2}}=\sum_{i=1}^{n}\frac{(n-1)!}{(i-1)!(n-i)!}f(i)2^{\binom{n-i}{2}}$
 
$(n-1)!$ 似乎有点碍事,除掉!!
 
$\frac{2^{\binom{n}{2}}}{(n-1)!}=\sum_{i=1}^{n}\frac{f(i)2^{\binom{n-i}{2}}}{(i-1)!(n-i)!}$
 
看起来像不像卷积 ??
——似乎不太像.
 
不急不急QAQ,再定义几个函数:
定义 $F(x)=\sum_{i=1}^{\infty}\frac{2^{\binom{i}{2}}}{(i-1)!}$
 
定义 $G(x)=\sum_{i=1}^{\infty}\frac{f(i)}{(i-1)!}$
定义 $H(x)=\sum_{i=0}^{\infty}\frac{2^{\binom{i}{2}}}{i!}$
 
令函数 $X_{i}$ 表示 多项式 $X$ 的第 $i$ 项系数.
 
观察 $\frac{2^{\binom{n}{2}}}{(n-1)!}=\sum_{i=1}^{n}\frac{f(i)2^{\binom{n-i}{2}}}{(i-1)!(n-i)!}$
 
得出: $F_{n}=\sum_{i=1}^{n}G_{i}H_{n-i}$
 
现在,能看出这个是卷积了吧!
 
即 $F(x)=G(x)H(x)$
 
我们要求的是 $G(x)$,则 $G(x)=F(x)H(x)^{-1}$.
 
来一波多项式求逆即可.  
 

Code:

#include 
#define N 3333300#define mod 1004535809 #define ll long long #define setIO(s) freopen(s".in","r",stdin) #define shut fclose(stdin),fclose(stdout) using namespace std;int qpow(int x,int y){ int tmp = 1; while(y) { if(y&1) tmp=1ll*tmp*x%mod; x=1ll*x*x%mod,y>>=1; } return tmp; }namespace NTT{ int a[N],b[N],f[N],g[N]; void NTT(int *a,int len,int opt){ for(int i = 0,k = 0;i < len; ++i) { if(i > k) swap(a[i],a[k]); for(int j = len >> 1;(k^=j)
>=1); } for(int k = 2;k <= len;k <<= 1) { int t = (k>>1),x=qpow(3,(mod-1)/k); if(opt==-1) x=qpow(x,mod-2); for(int i=0;i
>1); for(int i=0;i
<= n;m <<= 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]=qpow(2,1ll*(i-1)*i/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; NTT::solve(G,D,m); NTT::NTT(D,m,1);NTT::NTT(C,m,1); for(int i=0;i

  

转载于:https://www.cnblogs.com/guangheli/p/10935598.html

你可能感兴趣的文章
Linux Oracle服务启动&停止脚本与开机自启动[转]
查看>>
(转)利用CAS算法实现通用线程安全状态机
查看>>
C# 集合类(六):Dictionary 泛型集合
查看>>
Oracle12c安装出错
查看>>
Mono.Android 基础
查看>>
C#修改json文件中的某些值
查看>>
20170728xlVBA改转置一例
查看>>
20181013xlVba导入成绩
查看>>
Linux常用命令(第二版) --压缩解压缩命令
查看>>
Debian系列软件管理(第二版)
查看>>
熟悉sublime text3
查看>>
<mySql完全手册>2011022301
查看>>
浙江巨丰管业有限公司网站
查看>>
POJ 1047 Round and Round We Go
查看>>
语法分析生成器 - LEX
查看>>
第二本书第九课
查看>>
day15 接口与异常
查看>>
去培训机构参加IT培训值不值
查看>>
sql查询详解
查看>>
数据库知识点⑤
查看>>