Description

求\(n\)个点无重边、无自环、带标号的无向联通图个数,对\(1004535809\)(\(479 \times 2^{21} + 1\))取模。\(n \le 130000\)

Solution

模数好像是在提示了......这个模数非常适合\(NTT\)。

还是想题吧。首先问自己一个问题:不要求联通会不会?不会

不连通的话最多有\(\binom{n}{2}\)条边,总方案数就是这些边选不选的问题,即\(2^{\binom{n}{2}}\)。

我们令不要求联通的\(n\)个点形成的简单无向图个数为\(g_n\),联通图个数为\(f_n\),不难发现有这个柿子

\[g_n = \sum\limits_{i=1}^n \binom{n-1}{i-1}f_ig_{n-i}
\]

意思是我枚举\(1\)号点所在联通块的大小,然后把这个联通快孤立起来,剩下的点随便连边。

看到这个柿子想卷积?有组合数不方便卷,我们观察到

\[\binom{n-1}{i-1} = \frac{(n-1)!}{(n-i)!(i-1)!}
\]

不妨把两边同时乘\(\frac{1}{(n-1)!}\),然后再把剩下的分母分配一下

\[\frac{g_n}{(n-1)!} = \sum\limits_{i=1}^{n}\frac{f_i}{(i-1)!}\frac{g_{n-i}}{(n-i)!}
\]

这个柿子就非常好做,我们令\(h_n = \frac{g_n}{(n-1)!}\),然后用\(\frac{f_n}{(n-1)!}\)代替\(f_n\),\(\frac{g_n}{n!}\)代替\(g_n\),分别得到\(h,f,g\)的生成函数

\[H(x) = \sum\limits_{n=0}^{\infty} h_nx^n
\]

\[F(x) = \sum\limits_{n=0}^{\infty} f_nx^n
\]

\[G(x) = \sum\limits_{n=0}^{\infty} g_nx^n
\]

显然有

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

因为答案只与\(f_n\)有关,我们可以放到\(mod \ x^{n+1}\)下求\(F(x)\)。

\[F(x) \equiv G^{-1}(x)H(x) \ (mod \ x^{n+1})
\]

对\(G\)求逆过后与\(H\)卷积,就求出了\(F(x)\),然后答案就是\(f_n \times (n-1)!\)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int P=1004535809,g=3,ig=334845270,N=500010;
inline int add(int x,int y){return x+y>=P?x+y-P:x+y;}
inline int sub(int x,int y){return x-y<0?x-y+P:x-y;}
inline int fpow(int x,int y){
int ret=1; for (x%=P;y;y>>=1,x=1ll*x*x%P)
if (y&1) ret=1ll*ret*x%P;
return ret;
}
namespace Poly{
int rev[N];
void init(int limit){
for (int i=0;i<limit;i++)
rev[i]=rev[i>>1]>>1|((i&1)?limit>>1:0);
}
void ntt(int *f,int n,int flg){
for (int i=0;i<n;i++) if (rev[i]<i) swap(f[i],f[rev[i]]);
for (int k=1,len=2;len<=n;len<<=1,k<<=1){
int wn=fpow(flg==1?g:ig,(P-1)/len);
for (int i=0;i<n;i+=len){
for (int w=1,j=i;j<i+k;j++,w=1ll*w*wn%P){
int tmp=1ll*w*f[j+k]%P;
f[j+k]=sub(f[j],tmp),f[j]=add(f[j],tmp);
}
}
}
if (flg==-1){
int inv=fpow(n,P-2);
for (int i=0;i<n;i++) f[i]=1ll*f[i]*inv%P;
}
}
int F[N];
void getinv(int *f,int n,int *G){
if (n==1){G[0]=fpow(f[0],P-2);return;}
getinv(f,(n+1)>>1,G);
int limit=1; while(limit<=2*n)limit<<=1; init(limit);
for (int i=0;i<n;i++) F[i]=f[i];
// cout<<"wtf: "; for (int i=0;i<n;i++) cout<<G[i]<<" "; cout<<endl;
for (int i=n;i<limit;i++) F[i]=G[i]=0;
ntt(F,limit,1),ntt(G,limit,1);
for (int i=0;i<limit;i++) G[i]=1ll*G[i]*sub(2,1ll*F[i]*G[i]%P)%P;
ntt(G,limit,-1);
for (int i=n;i<limit;i++) G[i]=0;
}
}
using Poly::ntt;
using Poly::getinv;
int G[N],iG[N],H[N],F[N];
int ifac[N],inv[N],fac[N];
int main(){
int n; scanf("%d",&n);
fac[0]=fac[1]=ifac[0]=ifac[1]=1,inv[1]=1;
for (int i=2;i<=n;i++){
inv[i]=1ll*inv[P%i]*(P-P/i)%P;
ifac[i]=1ll*ifac[i-1]*inv[i]%P;
fac[i]=1ll*fac[i-1]*i%P;
}
G[0]=1;
for (int i=1;i<=n;i++)
G[i]=1ll*fpow(2,1ll*i*(i-1)/2%(P-1))*ifac[i]%P,H[i]=1ll*G[i]*i%P;
getinv(G,n+1,iG);
int limit=1; while(limit<=2*n)limit<<=1; Poly::init(limit);
ntt(iG,limit,1),ntt(H,limit,1);
for (int i=0;i<limit;i++) F[i]=1ll*iG[i]*H[i]%P;
ntt(F,limit,-1);
printf("%d\n",1ll*F[n]*fac[n-1]%P);
return 0;
}

[题解] LuoguP4841 [集训队作业2013]城市规划的更多相关文章

  1. [题解] BZOJ 3456 洛谷 P4841 [集训队作业2013]城市规划 多项式,分治FFT

    题目 令\(f_i\)表示n个点的答案.考虑容斥,用所有连边方案减去有多个连通块的方案.枚举1号点所在的连通块大小: \(f_i=2^{i(i-1)/2}-\sum_{j>0}^{i-1}f_j ...

  2. [洛谷P4841][集训队作业2013]城市规划

    传送门 题目大意 求出\(n\)个点的简单(无重边无自环)有标号无向连通图数目.\(n\leq 130000\). 题解 题意非常简单,但做起来很难.这是道生成函数经典题,博主当做例题学习用的.博主看 ...

  3. Solution -「集训队作业 2013」「洛谷 P4841」城市规划

    \(\mathcal{Description}\)   link.   求 \(n\) 个结点的简单无向连通图个数,对 \(1004535809~(479\times2^{21}+1)\) 取模.   ...

  4. 【UOJ#450】【集训队作业2018】复读机(生成函数,单位根反演)

    [UOJ#450][集训队作业2018]复读机(生成函数,单位根反演) 题面 UOJ 题解 似乎是\(\mbox{Anson}\)爷的题. \(d=1\)的时候,随便怎么都行,答案就是\(k^n\). ...

  5. 【UOJ#422】【集训队作业2018】小Z的礼物(min-max容斥,轮廓线dp)

    [UOJ#422][集训队作业2018]小Z的礼物(min-max容斥,轮廓线dp) 题面 UOJ 题解 毒瘤xzy,怎么能搬这种题当做WC模拟题QwQ 一开始开错题了,根本就不会做. 后来发现是每次 ...

  6. 2017国家集训队作业Atcoder题目试做

    2017国家集训队作业Atcoder题目试做 虽然远没有达到这个水平,但是据说Atcoder思维难度大,代码难度小,适合我这种不会打字的选手,所以试着做一做 不知道能做几题啊 在完全自己做出来的题前面 ...

  7. 2017国家集训队作业[agc016b]Color Hats

    2017国家集训队作业[agc016b]Color Hats 题意: 有\(N\)个人,每个人有一顶帽子.帽子有不同的颜色.现在,每个人都告诉你,他看到的所有其它人的帽子共有多少种颜色,问有没有符合所 ...

  8. 2017国家集训队作业[agc016e]Poor Turkey

    2017国家集训队作业[agc016e]Poor Turkey 题意: 一开始有\(N\)只鸡是活着的,有\(M\)个时刻,每个时刻有两个数\(X_i,Y_i\),表示在第\(i\)个时刻在\(X_i ...

  9. 2017国家集训队作业[agc006f]Blackout

    2017国家集训队作业[agc006f]Blackout 题意: 有一个\(N*N\)的网格,一开始有\(M\)个格子被涂黑,给出这\(M\)个格子,和染色操作:如果有坐标为\((x,y),(y,z) ...

随机推荐

  1. dfs+记忆化搜索,求任意两点之间的最长路径

    C.Coolest Ski Route 题意:n个点,m条边组成的有向图,求任意两点之间的最长路径 dfs记忆化搜索 #include<iostream> #include<stri ...

  2. Problem A: Assembly Required K路归并

    Problem A: Assembly Required Princess Lucy broke her old reading lamp, and needs a new one. The cast ...

  3. NO22 Linux正则表达式--grep命令常用参数

    Linux正则表达式:  一.基础正则第一波字符说明: 示例: 二.基础正则第二波字符说明:  三.基础正则第二波字符说明: 示例:  grep:一般常用参数 示例:+和*  ?和.:  |:  () ...

  4. gitlab实现webhook触发jenkins 自动,构建,测试,push webhook构子 总结

    最新一直在学习 工作 + 学习 去掉 90%   所以blog  一直没更 真是很不好!  exsi ceph gitlab jenkins harbor k8s  docker-compose ap ...

  5. springboot启动不能加载数据库驱动Failed to determine a suitable driver class

    SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/G:/sharp/repo ...

  6. SQL state [72000]; error code [1461]; ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值 ; nested exception is java.sql.BatchUpdateException: ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值

    本文转自  https://www.cnblogs.com/yingsong/p/5685790.html 原 因:某一个字段本为varchar2(1024),但是实际要插入的值超过varchar2允 ...

  7. tomcat多实例配置

    有一台server上跑个tomcat的实例的情况,我遇到过这种情况,毕竟把多个应用部署到一个实例中,如果某个应用出了问题,导致tomcat奔溃,其他应用也gg了.闲话到此. 通常部署多实例就是解压多个 ...

  8. linux 查看ip、用户、时间对应执行的命令

    这个需要使用到history命令.可以加数字,返回最近执行的几条命令.如果不加数字会返回所有的历史命令. [root@localhost ~]# history 20 1015 rm stdin.lo ...

  9. delphi10.2 命令行编译x64脚本

    Build.bat @echo off @echo delphi x64编译测试 @cd /d %~dp0 @echo 设置Delphi参数信息 @set SourcePath=%~dp0.\src ...

  10. delphi base64编码

    需要uses IdCoderMIME: function TForm1.Base64E(Path: string): string;var filepath: string; filestream: ...