题意:

求出n个点的简单(无重边无自环)无向连通图数目.
方案数mod 1004535809(479 * 2 ^ 21 + 1)即可.

n<=130000


DP求方案

g(n) n个点所有图的方案数 显然2C(n,2)=2n(n-1)

f(n) n个点连通图的方案数

然后枚举第一个点所在连通块的点数

g(n)=∑i=1..n-1{C(n-1,i-1)*f(i)*g(n-i)}

代入g(n) 两边同除(n-1)!消掉那个组合数上面那块,就变成了卷积的形式

我不写了直接看Miskcoo的公式啦 http://blog.miskcoo.com/2015/05/bzoj-3456

然后C(x)=A(x)*B(x)

A(x)=C(x)*B(x)-1

放在mod (x>n) 意义下求逆元就行了 因为需要的是a[n]


多项式求逆元

去看Miskcoo的教程吧 http://blog.miskcoo.com/2015/05/polynomial-inverse

简单的思路就是知道A(x) mod (x[n/2]) 下的逆元求mod (xn) 下的逆元

方法就是两个同余的式子写出来一减,两边平方再同乘A(x) 再移项

说一点关于意义的理解吧:

A(x)=Q(x)B(x)+R(x) degR<degB

A(x)Ξ0 (mod xn) 就是说A(x)的0..n-1项系数都是0

A(x)B(x)Ξ1 (mod xn) 它们每一项都有xn,否则不可能余数只有1;所以也有xn/2;

注意:

1.最后要乘(n-1)! 不要乘(n-1)

2.多项式求逆元每次长度都不确定,不能先预处理二进制反转

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=3e5+5;
inline int read(){char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}
int P=1004535809,MOD=P;
ll Pow(ll a,ll b,ll MOD){ll ans=1;for(;b;b>>=1,a=a*a%MOD)if(b&1) ans=ans*a%MOD;return ans;
}
struct NTT{int n,rev[N];ll g;void ini(int m){n=1;while(n<m) n<<=1;/*int k=0;while((1<<k)<n) k++;for(int i=0;i<n;i++){int t=0;for(int j=0;j<k;j++) if(i&(1<<j)) t|=(1<<(k-j-1));rev[i]=t;}*/g=3;}void transform(int *a,int flag,int n){int k=0;while((1<<k)<n) k++;for(int i=0;i<n;i++){int t=0;for(int j=0;j<k;j++) if(i&(1<<j)) t|=(1<<(k-j-1));if(t<i) swap(a[i],a[t]);}for(int l=2;l<=n;l<<=1){int m=l>>1;ll wn=Pow(g,flag==1?(P-1)/l:P-1-(P-1)/l,P);for(int *p=a;p!=a+n;p+=l){ll w=1;for(int k=0;k<m;k++){ll t=w*p[k+m]%P;p[k+m]=(p[k]-t+P)%P;p[k]=(p[k]+t)%P;w=w*wn%P;}}}if(flag==-1){ll inv=Pow(n,P-2,P);for(int i=0;i<n;i++) a[i]=a[i]*inv%P;}}int c[N];void test(int *a,int n){for(int i=0;i<n;i++) printf("%d ",a[i]);puts("");}void polyInv(int deg,int *a,int *b){if(deg==1) b[0]=Pow(a[0],P-2,P);else{polyInv((deg+1)>>1,a,b);int n=1;while(n< deg<<1) n<<=1;copy(a,a+deg,c);fill(c+deg,c+n,0);transform(c,1,n);transform(b,1,n);for(int i=0;i<n;i++)b[i]=(ll)b[i]*(2-(ll)b[i]*c[i]%P+P)%P;transform(b,-1,n);fill(b+deg,b+n,0);}}
}fft;
int n,inv[N],invFac[N],poc[N],A[N],B[N],C[N];
void getInv(int n){inv[1]=invFac[0]=1;for(int i=1;i<=n;i++){if(i!=1) inv[i]=-(ll)P/i*inv[P%i]%P;if(inv[i]<0) inv[i]+=P;invFac[i]=(ll)invFac[i-1]*inv[i]%P;}
}
int main(){//freopen("in","r",stdin);n=read();fft.ini(n);getInv(n);poc[0]=poc[1]=1;for(int i=2;i<=n;i++) poc[i]=Pow(2,(ll)i*(i-1)>>1%(P-1),P);for(int i=0;i<=n;i++) B[i]=(ll)poc[i]*invFac[i]%P;for(int i=1;i<=n;i++) C[i]=(ll)poc[i]*invFac[i-1]%P;//printf("CC %d\n",C[i]);
    fft.polyInv(fft.n,B,A);fft.n<<=1;fft.transform(A,1,fft.n);fft.transform(C,1,fft.n);for(int i=0;i<fft.n;i++) A[i]=(ll)A[i]*C[i]%P;//,printf("ABC %d %d %d\n",i,A[i],C[i]);
 fft.transform(A,-1,fft.n);printf("%lld",(ll)A[n]*Pow(invFac[n-1],P-2,P)%P);
}

BZOJ 3456: 城市规划 [多项式求逆元 DP]相关推荐

  1. BZOJ 3456 城市规划 (组合计数、DP、FFT)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3456 著名的多项式练习题,做法也很多,终于切掉了纪念 首先求一波递推式: 令\(F(n ...

  2. bzoj 3456: 城市规划【NTT+多项式求逆】

    参考:http://blog.miskcoo.com/2015/05/bzoj-3456 首先推出递推式(上面的blog讲的挺清楚的),大概过程是正难则反,设g为n个点的简单(无重边无自环)无向图数目 ...

  3. bzoj#3456. 城市规划

    bzoj#3456. 城市规划 题目描述 Solution 用组合意义推很简单. iii个点的简单无向图个数为2(i2)2^{\tbinom{i}{2}}2(2i​)个. 则其EGFEGFEGF为 G ...

  4. BZOJ 3456: 城市规划(dp+多项式求逆)

    传送门 解题思路 这道题就是求带标号的无向连通图个数,首先考虑\(O(n^2)\)的做法,设\(f_i\)表示有\(i\)个节点的无向连通图个数,那么考虑容斥,先把所有的无向图求出,即为\(2^{C( ...

  5. P4841,jzoj3303-城市规划【NTT,多项式求逆,dp】

    正题 题目链接:https://www.luogu.org/problemnew/show/P4841 题目大意 求nnn个点的简单联通无向图的个数. 解题思路 首先考虑n2n^2n2,我们设gig_ ...

  6. 【BZOJ】3456: 城市规划 动态规划+多项式求逆

    [题意]求n个点的带标号无向连通图个数 mod 1004535809.n<=130000. [算法]动态规划+多项式求逆 [题解]设$g_n$表示n个点的无向图个数,那么显然 $$g_n=2^{ ...

  7. 【BZOJ】3456: 城市规划(多项式求ln)

    题解 在我写过分治NTT,多项式求逆之后 我又一次写了多项式求ln 我们定义一个数列的指数型生成函数为 \(\sum_{i = 0}^{n} \frac{A_{i}}{i!} x^{i}\) 然后这个 ...

  8. #3456. 城市规划(生成函数,多项式求逆)

    #3456. 城市规划 设fnf_nfn​为nnn个点的的点的简单无向连通图数目,gng_ngn​为nnn个点的简单无向图个数(不要求联通). 对于gng_ngn​显然有gn=2n(n−1)2g_n ...

  9. (每日一题)P4841 [集训队作业2013]城市规划 (无向连通图计数)(普通生成函数 + 多项式求逆)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 每日一题(莫反 / 多项式 / 母函数 / 群论) 2021.4.14 生成函数 + 多项式求逆 Pr ...

最新文章

  1. css sprite技巧详解
  2. The RSpec Book笔记《一》初步认识TDD,BDD,RSpec,Cucumber
  3. Win64 驱动内核编程-30.枚举与删除线程回调
  4. 计算机硬件的基本组成
  5. mysql执行出错:Table 'k_user' is read only
  6. 无法安装计算机的启动配置,“windows 无法更新计算机的启动配置。安装无法继续”这样解决...
  7. springboot访问静态页面404_解决 springboot 2.x 访问静态资源 404的问题
  8. Perl 中的正则表达式
  9. mpu 配置内存空间_mpu内存保护单元功能及工作原理
  10. MTU(Maximum Transmission Unit),最大传输单元
  11. JDK时区与电脑系统时区不一致,导致时间new date不对
  12. 轻松生成小程序分享海报
  13. 可以扦插的花有哪些?
  14. 对vector/string执行insert/erase操作后迭代器的情况说明
  15. Unity 常用API以及C# 工具类的使用
  16. 使用变量替换批量部署GoldenGate
  17. Windows10三月更新后,电脑打印文件时蓝屏解决方案
  18. Pandas安装与对象使用
  19. DES算法理解--附《密码编码学与网络安全(第七版)》课后练习题答案
  20. 小技巧!Win10系统怎样恢复使用Win7中的照片查看器?非常简单!

热门文章

  1. java学习规划-转的
  2. MySQL数据类型之数字类型详细解析
  3. Memory Information on Windows Mobile(续)
  4. 2.算法-程序的灵魂
  5. 全国计算机二级计基础题第十五套,2014计算机二级VF试题及答案解析(第十五套)...
  6. centos在文本中搜索字符串_CentOS查找所有文件中某个字符串
  7. Python进程和线程保姆式教学,1个台机子多只手干活的秘籍
  8. hive 列转行_掌握这个SQL技巧超越80%的人——行转列/列转行
  9. html弹性重叠,关于html5弹性布局(2)
  10. linux环境对apk文件写入数据,Linux下7zip命令apk中插入文件标识渠道批量打包