【题解】P4841 城市规划

P4841 城市规划

超级弱化版本(DP):POJ - 1737

两张图不同当且仅当边的分布不一样的时候,带编号最后乘一个阶乘即可,现在最主要的问题就是"联通"这个条件。

我首先考虑的容斥,"随意连不联通"的方案太好算了,\(2^{n(n-1)/2}\),但是发现不会降低复杂度,因为"联通"和"随意连不联通"不好容斥,他们之间的关系不是简单的关系,所以不行了。

其次考虑DP,仍然发现不行,数据范围太大,之前做过一道POJ - 1737的\(DP\)是\(O(n^2)\)的,那个式子不会优化,可能可以用\(NTT\)优化一下吧,不会。

但是这些思考给了我们启发,考虑一下之前容斥的时候,"\(f(x)\)联通"和"\(g(x)\)随意连不联通"的关系究竟是什么

一张随意联通图是由很多联通图组成,很多究竟是哪些?究竟要哪些自变量?显然既要枚举有多少联通图,也要确定每张连通图的大小。这就是我们之前不能简单容斥的原因。那么,对于这样的问题,既要枚举多少,也要枚举每个的状态的计数怎么办?

一个很好的手法就是构造母函数,我们知道乘法的本质就是组合(大雾),因为括号乘以括号就自动帮我们完成了枚举多少和枚举状态的工作。

令\(f(x)\)表示\(x\)个无区别点的连通图方案数,\(g(x)\)表示\(x\)个无区别点的随意联通图方案数

又令

\[G(x)=\sum_{i=0}^{\inf} g(i)x^i
\\
F(x)=\sum_{i=0}f(i)x^i
\]

则有

\[G(x)=\sum_{i=0}^{\inf} \dfrac {(F(x))^i} {i!}
\]

看不懂式子的我只想说取追踪\(G(x)\)的\(x^i\)系数来源就懂了,要除以一个阶乘是因为要消去顺序,\((F(x))^i\)是有序的。

联想到指数型生成函数

知道\(e^x\)的麦克劳林级数

\[e^x=\sum_{i=0}^{\inf} \dfrac {x^i} {i!}
\]

观察一下我们\(G(x)\)的式子,解出来了,结果很显然就是

\[G(x)= e^{F(x)}
\]

\[F(x)=\ln G(x)
\]

左转默写板子,其中\(G(x)\)的\([x^i]=2^{i(i-1)/2} \times \dfrac 1 {i!}\)

  1. //@winlere
  2. #include<iostream>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<algorithm>
  6. #include<cmath>
  7. using namespace std; typedef long long ll;
  8. inline int qr(){
  9. register int ret=0,f=0;
  10. register char c=getchar();
  11. while(c<48||c>57)f|=c==45,c=getchar();
  12. while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
  13. return f?-ret:ret;
  14. }
  15. const int maxn=1<<18|1;
  16. int jc[maxn],inv[maxn],r[maxn];
  17. const int mod=1004535809;
  18. const int g=3;
  19. inline int ksm(const int&,const ll&);
  20. const int gi=ksm(3,mod-2);
  21. inline int ksm(const int&base,const ll&p){
  22. register int ret=1;
  23. for(register int t=p%(mod-1),b=base%mod;t;t>>=1,b=1ll*b*b%mod)
  24. if(t&1) ret=1ll*ret*b%mod;
  25. return ret;
  26. }
  27. inline void getr(const int&len){
  28. static int savlen=0;
  29. if(len==savlen)return;
  30. int cnt=0;
  31. for(register int t=1;t<len;t<<=1)++cnt;
  32. for(register int t=0;t<len;++t) r[t]=r[t>>1]>>1|(t&1)<<cnt>>1;
  33. }
  34. inline void NTT(int*a,const int&len,const int&tag){
  35. getr(len);
  36. for(register int t=0;t<len;++t)
  37. if(r[t]>t)swap(a[t],a[r[t]]);
  38. int *a0,*a1,s=g;
  39. if(tag!=1)s=gi;
  40. for(register int t=1,wn;t<len;t<<=1){
  41. wn=ksm(s,(mod-1)/(t<<1));
  42. for(register int i=0;i<len;i+=t<<1){
  43. a1=(a0=a+i)+t;
  44. for(register int k=0,w=1,m;k<t;++k,++a1,++a0,w=1ll*w*wn%mod){
  45. m=1ll**a1*w%mod;
  46. *a1=(*a0+mod-m)%mod;
  47. *a0=(*a0+m)%mod;
  48. }
  49. }
  50. }
  51. if(tag!=1) for(register int t=0,w=ksm(len,mod-2);t<len;++t)
  52. a[t]=1ll*a[t]*w%mod;
  53. }
  54. void INV(int*a,int*b,const int&len){
  55. if(len==1){b[0]=ksm(a[0],mod-2);return;}
  56. INV(a,b,len>>1);
  57. static int A[maxn],B[maxn];
  58. for(register int t=0;t<len<<1;++t) A[t]=B[t]=0;
  59. for(register int t=0;t<len;++t) A[t]=a[t],B[t]=b[t];
  60. NTT(A,len<<1,1);NTT(B,len<<1,1);
  61. for(register int t=0;t<len<<1;++t) A[t]=1ll*A[t]*B[t]%mod*B[t]%mod;
  62. NTT(A,len<<1,-1);
  63. for(register int t=0;t<len;++t) b[t]=((b[t]+b[t])%mod-A[t]+mod)%mod;
  64. }
  65. inline void inter(int*a,int*b,const int&len){
  66. for(register int t=len-1;t;--t)
  67. b[t]=1ll*a[t-1]*ksm(t,mod-2)%mod;
  68. b[0]=0;
  69. }
  70. inline void dev(int*a,int*b,const int&len){
  71. for(register int t=0;t<len-1;++t)
  72. b[t]=1ll*(t+1)*a[t+1]%mod;
  73. b[len-1]=0;
  74. }
  75. inline void LN(int*a,int*b,const int&len){
  76. static int A[maxn],B[maxn];
  77. for(register int t=0;t<len<<1;++t) A[t]=B[t]=0;
  78. INV(a,A,len);
  79. dev(a,B,len);
  80. NTT(A,len<<1,1); NTT(B,len<<1,1);
  81. for(register int t=0;t<len<<1;++t) B[t]=1ll*B[t]*A[t]%mod;
  82. NTT(B,len<<1,-1);
  83. inter(B,b,len);
  84. }
  85. inline void pre(const int&n){
  86. jc[0]=inv[0]=1;
  87. for(register int t=1;t<=n;++t)
  88. jc[t]=1ll*jc[t-1]*t%mod;
  89. inv[n]=ksm(jc[n],mod-2);
  90. for(register int t=n-1;t;--t)
  91. inv[t]=1ll*inv[t+1]*(t+1)%mod;
  92. }
  93. int t1[maxn],t2[maxn],n,k;
  94. int main(){
  95. n=qr();
  96. pre(n);
  97. int k=1;
  98. while(k<=n+1)k<<=1;
  99. for(register int t=0;t<k;++t) t1[t]=1ll*ksm(2,1ll*t*(t-1ll)>>1)*inv[t]%mod;
  100. LN(t1,t2,k);
  101. printf("%lld\n",1ll*t2[n]*jc[n]%mod);
  102. return 0;
  103. }

【题解】P4841 城市规划(指数型母函数+多项式Ln)的更多相关文章

  1. hdu1521 排列组合(指数型母函数)

    题意: 有n种物品,并且知道每种物品的数量ki.要求从中选出m件物品的排数.         (全题文末) 知识点: 普通母函数 指数型母函数:(用来求解多重集的排列问题) n个元素,其中a1,a2, ...

  2. 【BZOJ3456】轩辕朗的城市规划 无向连通图计数 CDQ分治 FFT 多项式求逆 多项式ln

    题解 分治FFT 设\(f_i\)为\(i\)个点组成的无向图个数,\(g_i\)为\(i\)个点组成的无向连通图个数 经过简单的推导(枚举\(1\)所在的连通块大小),有: \[ f_i=2^{\f ...

  3. hdu1521:排列组合---指数型母函数

    题意: n种元素,每种有 ni个,选出 m 个的排列有多少种 题解: 指数型母函数的裸题 x^n 项的系数为  an/n!.... 代码如下: #include <iostream> #i ...

  4. 【XSY2730】Ball 多项式exp 多项式ln 多项式开根 常系数线性递推 DP

    题目大意 一行有\(n\)个球,现在将这些球分成\(k\) 组,每组可以有一个球或相邻两个球.一个球只能在至多一个组中(可以不在任何组中).求对于\(1\leq k\leq m\)的所有\(k\)分别 ...

  5. 母函数 <普通母函数(HDU - 1028 ) && 指数型母函数(hdu1521)>

    给出我初学时看的文章:母函数(对于初学者的最容易理解的) 普通母函数--------->HDU - 1028 例题:若有1克.2克.3克.4克的砝码各一 枚,能称出哪几种重量?各有几种可能方案? ...

  6. HDU 5362 Just A String 指数型母函数

    题面 Description 用m种字母构造一个长度为n的字符串,如果一个字符串的字母重组后可以形成一个回文串则该串合法,问随机构成的长为n的字符串的合法子串数目期望值. Input 第一行一整数T表 ...

  7. HDU2065 “红色病毒”问题 (指数型母函数经典板题)

    题面 医学界发现的新病毒因其蔓延速度和Internet上传播的"红色病毒"不相上下,被称为"红色病毒",经研究发现,该病毒及其变种的DNA的一条单链中,胞嘧啶, ...

  8. hdu1521 指数型母函数

    排列组合 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  9. HDU 2065 “红色病毒”问题 --指数型母函数

    这种有限制的类棋盘着色问题一般可以用指数型母函数来解决,设Hn表示这样的着色数,首先H0=1,则Hn等于四个字母的(A,B,C,D)的多重集合的n排列数,其中每个字母的重数是无穷,且要求A,C出现的次 ...

随机推荐

  1. 微服务开源生态报告 No.1

    从关注开源,到使用开源,再到参与开源贡献,越来越多的国内开发者通过开源技术来构建业务. 截止目前,Arthas / Dubbo / ChaosBalde / Nacos / RocketMQ / Se ...

  2. 自定义View系列教程06--详解View的Touch事件处理

    深入探讨Android异步精髓Handler 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Andr ...

  3. Libev源码分析07:Linux下的eventfd简介

    #include <sys/eventfd.h> int eventfd(unsigned int initval, int flags); eventfd创建一个eventfd对象,该对 ...

  4. AtCoder Beginner Contest 077 D Small Multiple(最短路)

    水过前三道题之后,一直在写这个题,做不对.总有那么几组数据过不去... 看了看题解是最短路,这思路感觉很神奇.看了下唯一做出来这题的那人的代码,是搜索做的. 标程: 对每个数字x,向x+1建一条花费为 ...

  5. oracle comment on的用法

    转:http://www.2cto.com/database/201109/106249.html   oracle中用comment on命令给表或字段加以说明,语法如下:COMMENT ON  { ...

  6. ThinkPHP商城实战

    ThinkPHP3.2.3商城实战教程,需要的联系我,QQ:1844912514 千万级php电商秒杀项目实战  ,需要的联系我,QQ:1844912514

  7. codeforces 609C

    #include<bits/stdc++.h> using namespace std; ],c[]; int main() { int n,i; while(cin >> n ...

  8. H3C 在接口上应用ACL

  9. linux如何查看nginx是否启动

    Nginx是一个高性能的反向代理服务器,现在一般作为我们网站或其他Web服务的第一层代理,用户在浏览器请求首先经过的就是Nginx服务. 如果Nginx服务没有启动或异常结束,将会影响Web服务的正常 ...

  10. centos linux mysql 10060远程错误代码

    Navicat for MySQL远程连接数据错误代码10060 1.登陆远程linux服务器命令界面 vim /etc/sysconfig/iptables  进入防火墙配置修改 增加以下两条防火墙 ...