[BZOJ3456]城市规划(生成函数+多项式求逆+多项式求ln)
城市规划
时间限制:40s 空间限制:256MB
题目描述
刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了.
刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得整个国家的任意两个城市都直接或间接的连通. 为了省钱,
每两个城市之间最多只能有一条直接的贸易路径. 对于两个建立路线的方案, 如果存在一个城市对, 在两个方案中是否建立路线不一样,
那么这两个方案就是不同的, 否则就是相同的. 现在你需要求出一共有多少不同的方案.
好了, 这就是困扰阿狸的问题. 换句话说, 你需要求出n个点的简单(无重边无自环)无向连通图数目.
由于这个数字可能非常大, 你只需要输出方案数mod 1004535809(479 * 2 ^ 21 + 1)即可.
输入格式
仅一行一个整数n(<=130000)
输出格式
仅一行一个整数, 为方案数 mod 1004535809.
样例输入
3
样例输出
4
提示
对于 100%的数据, n <= 130000
题目来源
没有写明来源
传说中FFT应用的最高境界?现在恐怕配不上这个称号了。
http://blog.miskcoo.com/2015/05/bzoj-3456
解法一:
先按照惯例减弱条件限制,不要求图连通,再将连通和不联通之间的递推关系式化成卷积的形式。最后直接上生成函数,在模$x^{n+1}$下求多项式的逆元即可。
次数界放宽!递归求逆元的时候次数界要放成两倍!
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
using namespace std; const int N=,mod=,g=;
int n,m,a[N],b[N],lg[N<<],fac[N],fin[N],tmp[N],c[N],b1[N],rev[N]; int ksm(int a,int b){
int res;
for (res=; b; a=1ll*a*a%mod,b>>=)
if (b&) res=1ll*res*a%mod;
return res;
} void DFT(int a[],int n,int f){
for (int i=; i<n; i++) if (i<rev[i]) swap(a[i],a[rev[i]]);
for (int i=; i<n; i<<=){
int wn=ksm(g,(f==) ? (mod-)/(i<<) : (mod-)-(mod-)/(i<<));
for (int p=i<<,j=; j<n; j+=p){
int w=;
for (int k=; k<i; k++,w=1ll*w*wn%mod){
int x=a[j+k],y=1ll*w*a[i+j+k]%mod; a[j+k]=(x+y)%mod; a[i+j+k]=(x-y+mod)%mod;
}
}
}
if (f==) return;
int inv=ksm(n,mod-);
for (int i=; i<n; i++) a[i]=1ll*a[i]*inv%mod;
} void get(int a[],int b[],int l){
if (l==){ b[]=ksm(a[],mod-); return ;}
get(a,b,l>>); int n=l<<;
for (int i=; i<l; i++) tmp[i]=a[i],tmp[i+l]=; for (int i=; i<n; i++) rev[i]=(rev[i>>]>>)|((i&)<<(lg[n]-));
DFT(tmp,n,); DFT(b,n,);
for (int i=; i<n; i++) tmp[i]=1ll*b[i]*(-1ll*tmp[i]*b[i]%mod+mod)%mod;
DFT(tmp,n,-); for (int i=; i<l; i++) b[i]=tmp[i],b[i+l]=;
} int main(){
freopen("bzoj3456.in","r",stdin);
freopen("bzoj3456.out","w",stdout);
scanf("%d",&n); fac[]=fin[]=; lg[]=;
rep(i,,n<<) lg[i]=lg[i>>]+;
rep(i,,n) fac[i]=1ll*fac[i-]*i%mod;
fin[n]=ksm(fac[n],mod-);
for (int i=n-; i; i--) fin[i]=1ll*fin[i+]*(i+)%mod;
rep(i,,n) b[i]=1ll*ksm(,1ll*i*(i-)/%(mod-))*fin[i]%mod;
rep(i,,n) c[i]=1ll*ksm(,1ll*i*(i-)/%(mod-))*fin[i-]%mod;
for (m=; m<=n; m<<=); get(b,b1,m);
DFT(c,m<<,); DFT(b1,m<<,);
for (int i=; i<(m<<); i++) c[i]=1ll*c[i]*b1[i]%mod;
DFT(c,m<<,-); printf("%lld\n",1ll*c[n]*fac[n-]%mod);
return ;
}
解法二:指数型生成函数
惊奇地发现正好要求的函数可以放在exp的指数上,多项式求ln即可。
形式幂级数什么的真是太有意思了。
https://blog.csdn.net/u014609452/article/details/56291323
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
using namespace std; const int N=,mod=,g=;
int n,m,G[N],G1[N],invG[N],lg[N<<],fac[N],fin[N],tmp[N],c[N],b1[N],rev[N]; int ksm(int a,int b){
int res;
for (res=; b; a=1ll*a*a%mod,b>>=)
if (b&) res=1ll*res*a%mod;
return res;
} void DFT(int a[],int n,int f){
for (int i=; i<n; i++) if (i<rev[i]) swap(a[i],a[rev[i]]);
for (int i=; i<n; i<<=){
int wn=ksm(g,(f==) ? (mod-)/(i<<) : (mod-)-(mod-)/(i<<));
for (int p=i<<,j=; j<n; j+=p){
int w=;
for (int k=; k<i; k++,w=1ll*w*wn%mod){
int x=a[j+k],y=1ll*w*a[i+j+k]%mod; a[j+k]=(x+y)%mod; a[i+j+k]=(x-y+mod)%mod;
}
}
}
if (f==) return;
int inv=ksm(n,mod-);
for (int i=; i<n; i++) a[i]=1ll*a[i]*inv%mod;
} void get(int a[],int b[],int l){
if (l==){ b[]=ksm(a[],mod-); return ;}
get(a,b,l>>); int n=l<<;
for (int i=; i<l; i++) tmp[i]=a[i],tmp[i+l]=; for (int i=; i<n; i++) rev[i]=(rev[i>>]>>)|((i&)<<(lg[n]-));
DFT(tmp,n,); DFT(b,n,);
for (int i=; i<n; i++) tmp[i]=1ll*b[i]*(-1ll*tmp[i]*b[i]%mod+mod)%mod;
DFT(tmp,n,-); for (int i=; i<l; i++) b[i]=tmp[i],b[i+l]=;
} int main(){
freopen("bzoj3456.in","r",stdin);
freopen("bzoj3456.out","w",stdout);
scanf("%d",&n); fac[]=fin[]=; lg[]=;
rep(i,,n<<) lg[i]=lg[i>>]+;
rep(i,,n) fac[i]=1ll*fac[i-]*i%mod;
fin[n]=ksm(fac[n],mod-);
for (int i=n-; i; i--) fin[i]=1ll*fin[i+]*(i+)%mod; G[]=G[]=; G1[n]=;
rep(i,,n) G[i]=1ll*ksm(,(1ll*i*(i-)/)%(mod-))*fin[i]%mod;
rep(i,,n) G1[i-]=1ll*G[i]*i%mod; for (m=; m<=n; m<<=); get(G,invG,m); m<<=;
DFT(G1,m,); DFT(invG,m,);
for (int i=; i<m; i++) G1[i]=1ll*invG[i]*G1[i]%mod;
DFT(G1,m,-); printf("%lld\n",(1ll*G1[n-]*ksm(n,mod-)%mod)*fac[n]%mod);
return ;
}
[BZOJ3456]城市规划(生成函数+多项式求逆+多项式求ln)的更多相关文章
- FFT模板 生成函数 原根 多项式求逆 多项式开根
FFT #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> ...
- NTT+多项式求逆+多项式开方(BZOJ3625)
定义多项式$h(x)$的每一项系数$h_i$,为i在c[1]~c[n]中的出现次数. 定义多项式$f(x)$的每一项系数$f_i$,为权值为i的方案数. 通过简单的分析我们可以发现:$f(x)=\fr ...
- 【BZOJ3456】轩辕朗的城市规划 无向连通图计数 CDQ分治 FFT 多项式求逆 多项式ln
题解 分治FFT 设\(f_i\)为\(i\)个点组成的无向图个数,\(g_i\)为\(i\)个点组成的无向连通图个数 经过简单的推导(枚举\(1\)所在的连通块大小),有: \[ f_i=2^{\f ...
- bzoj 3456 城市规划——分治FFT / 多项式求逆 / 多项式求ln
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3456 分治FFT: 设 dp[ i ] 表示 i 个点时连通的方案数. 考虑算补集:连通的方 ...
- 2019.01.01 bzoj3625:小朋友和二叉树(生成函数+多项式求逆+多项式开方)
传送门 codeforces传送门codeforces传送门codeforces传送门 生成函数好题. 卡场差评至今未过 题意简述:nnn个点的二叉树,每个点的权值KaTeX parse error: ...
- 【BZOJ3625】【codeforces438E】小朋友和二叉树 生成函数+多项式求逆+多项式开根
首先,我们构造一个函数$G(x)$,若存在$k∈C$,则$[x^k]G(x)=1$. 不妨设$F(x)$为最终答案的生成函数,则$[x^n]F(x)$即为权值为$n$的神犇二叉树个数. 不难推导出,$ ...
- [Codeforces438E][bzoj3625] 小朋友和二叉树 [多项式求逆+多项式开根]
题面 传送门 思路 首先,我们把这个输入的点的生成函数搞出来: $C=\sum_{i=0}^{lim}s_ix^i$ 其中$lim$为集合里面出现过的最大的数,$s_i$表示大小为$i$的数是否出现过 ...
- BZOJ 3625 [Codeforces Round #250]小朋友和二叉树 ——NTT 多项式求逆 多项式开根
生成函数又有奇妙的性质. $F(x)=C(x)*F(x)*F(x)+1$ 然后大力解方程,得到一个带根号的式子. 多项式开根有解只与常数项有关. 发现两个解只有一个是成立的. 然后多项式开根.求逆. ...
- P6295-有标号 DAG 计数【多项式求逆,多项式ln】
正题 题目链接:https://www.luogu.com.cn/problem/P6295 题目大意 求所有\(n\)个点的弱联通\(DAG\)数量. \(1\leq n\leq 10^5\) 解题 ...
- luogu P4725 多项式对数函数 (模板题、FFT、多项式求逆、求导和积分)
手动博客搬家: 本文发表于20181125 13:25:03, 原地址https://blog.csdn.net/suncongbo/article/details/84487306 题目链接: ht ...
随机推荐
- 【转载】Lua中实现类的原理
原文地址 http://wuzhiwei.net/lua_make_class/ 不错,将metatable讲的很透彻,我终于懂了. --------------------------------- ...
- Java连接Oracle数据库的三种连接方式
背景: 这两天在学习Oracle数据库,这里就总结下自己上课所学的知识,同时记录下来,方便整理当天所学下的知识,也同时方便日后自己查询. SQL语句的话,这里我就不多讲了,感觉和其他的数据库(MySQ ...
- 如何入门 Python 爬虫?
作者:谢科 来源:知乎链接:https://www.zhihu.com/question/20899988/answer/24923424 著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...
- gcc中的内嵌汇编语言(Intel i386平台)
[转]http://bbs.chinaunix.net/thread-2149855-1-1.html 一.声明 虽然Linux的核心代码大部分是用C语言编写的,但是不可避免的其中还是有一部分是用汇 ...
- 浅析linux内核中timer定时器的生成和sofirq软中断调用流程【转】
转自:http://blog.chinaunix.net/uid-20564848-id-73480.html 浅析linux内核中timer定时器的生成和sofirq软中断调用流程 mod_time ...
- monkey测试===easyMonkey测试【推荐】
easymonkey测试: easymonkey是基于monkey测试的一个二次开发工具.(关于monkey测试参见之前blog) easymonkey的特点就是方便,解决了很多参数命令上设置的麻烦, ...
- centos安装--两张光盘
不是有两个ISO吗?你在别的电脑上打开第二个iso,就可以看到里面是openoffice的语言包.你安装的时候出现的提示是找不到“openoffice.org-langpack-zh-TW-3.1.1 ...
- [c++,bson] linux 使用 BSON 编程[www]
[c++,bson] linux 使用 BSON 编程 http://blog.chinaunix.net/uid-28595538-id-4987410.html 1.js db=db.getSib ...
- 经典卷积网络模型 — VGGNet模型笔记
一.简介 VGGNet是计算机视觉组(Visual Geometry Group)和Google DeepMind公司的研究员一起研究的深度卷积神经网络.VGGNet探索了卷积神经网络深度与性能之间的 ...
- ansible安装和配置
一.安装ansible准备 //安装准备 .两台机器 172.7.15.106 172.7.15.111 .设置hostname以及hosts 172.7.15.106 web9.lulu.com 1 ...