一周一博客二专题计划

题面

n 个点的简单 (无重边无自环) 有标号无向连通图数目。

看着就很典

思路

设\(f(n)\)为n点连通图数目。设\(g(n)\)为n点不一定联通图数目,显然直接枚举每条边是否存在,\(g(n)=2^{\frac{n*(n-1)}{2}}\)

\[g(n)=\sum_{i=1}^{n} \left( \begin{array}{c} n-1 \\ i-1 \end{array} \right) f(i)g(n-i)
\]

可看作枚举1号节点所在连通块的大小,组合数是从其他n-1个点中选出与1同联通块的点

很多博客都是推完式子然后发现卷积形式。其实应该看到多项式相乘,考虑卷积求解,化式子时尽量将i相关放在一起,n-i相关放在一起

而组合数上的n-1明显要拆出来

\[\frac{g(n)}{(n-1)!}=\sum_{i=1}^{n} \frac{f(i)}{(i-1)!} \frac{g(n-i)}{(n-i)!}
\]

很明显,设

\[a_i=\frac{f(i+1)}{i!}
\]
\[b_j=\frac{2^{\frac{j*(j-1)}{2}}}{j!}
\]
\[c_k=\frac{2^{\frac{k*(k+1)}{2}}}{k!}
\]

\[c_k=\sum_{i+j=k}a_ib_j
\]

NTT的式子已经出来了,不同的是此时我们已知\(c\)而想求\(a\),直接对\(b\)多项式求逆\(a=c*invb\)

答案\(f(n)=a_{n-1}*(n-1)!\)

代码


#include<bits/stdc++.h>
using namespace std;
const int MAX=2.7e5+10;
#define int long long
const int mod=1004535809;
int n,bl,bc,rev[MAX],a[MAX],b[MAX],f[MAX],g[MAX];
int fac[MAX],inv[MAX],c[MAX];
inline int read(){
int x=0,f=1;char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^'0');c=getchar();}
return x*f;
}
inline int power(int a,int b){
int res=1;
while(b){
if(b&1) res=res*a%mod;
a=a*a%mod;b>>=1;
}return res;
}inline void NTT(int*,int,int);
void solve(int);
inline void work(int len){
bl=1;bc=0;
while(bl<=len) bl<<=1,++bc;
for(int i=0;i<bl;++i)
rev[i]=(rev[i>>1]>>1)|((i&1)<<bc-1);
}
signed main(){
n=read();fac[0]=1;
for(int i=1;i<=n;++i) fac[i]=fac[i-1]*i%mod;
inv[n]=power(fac[n],mod-2);
for(int i=n-1;i>=0;--i) inv[i]=inv[i+1]*(i+1)%mod;
f[0]=1;c[0]=1;
for(int i=1;i<n;++i){
f[i]=power(2,(i-1)*i/2)*inv[i]%mod;
c[i]=power(2,i*(i+1)/2)*inv[i]%mod;
}
solve(n);work(n<<1);
NTT(g,bl,1);NTT(c,bl,1);
for(int i=0;i<bl;++i) g[i]=g[i]*c[i]%mod;
NTT(g,bl,-1);printf("%d",g[n-1]*fac[n-1]%mod);
}
void solve(int len){
if(len==1){g[0]=power(f[0],mod-2);return;}
solve(len+1>>1);work(len+n);
memcpy(a,f,sizeof(a));memset(b,0,sizeof(b));
for(int i=0;i<len+1>>1;++i) b[i]=g[i];
NTT(a,bl,1);NTT(b,bl,1);
for(int i=0;i<bl;++i) g[i]=b[i]*((2-a[i]*b[i]%mod+mod)%mod)%mod;
NTT(g,bl,-1);
}inline void NTT(int *a,int n,int op){
for(int i=0;i<n;++i)
if(i<rev[i]) swap(a[i],a[rev[i]]);
for(int i=1;i<n;i<<=1){
int wn=power(3,(op*(mod-1)/(i<<1)+mod-1)%(mod-1));
for(int j=0;j<n;j+=i<<1){
int w=1;
for(int k=0;k<i;++k){
int x=a[j+k],y=a[j+k+i]*w%mod;
a[j+k]=(x+y)%mod;a[j+k+i]=(x-y+mod)%mod;
w=w*wn%mod;
}
}
}if(op==-1){
int inv=power(n,mod-2);
for(int i=0;i<n;++i) a[i]=a[i]*inv%mod;
}
}

[集训队作业2013] 城市规划(NTT)的更多相关文章

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

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

  2. [题解] LuoguP4841 [集训队作业2013]城市规划

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

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

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

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

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

  5. UOJ #449. 【集训队作业2018】喂鸽子

    UOJ #449. [集训队作业2018]喂鸽子 小Z是养鸽子的人.一天,小Z给鸽子们喂玉米吃.一共有n只鸽子,小Z每秒会等概率选择一只鸽子并给他一粒玉米.一只鸽子饱了当且仅当它吃了的玉米粒数量\(≥ ...

  6. UOJ#428. 【集训队作业2018】普通的计数题

    #428. [集训队作业2018]普通的计数题 模型转化好题 所以变成统计有标号合法的树的个数. 合法限制: 1.根标号比子树都大 2.如果儿子全是叶子,数量B中有 3.如果存在一个儿子不是叶子,数量 ...

  7. [UOJ422][集训队作业2018]小Z的礼物——轮廓线DP+min-max容斥

    题目链接: [集训队作业2018]小Z的礼物 题目要求的就是最后一个喜欢的物品的期望得到时间. 根据$min-max$容斥可以知道$E(max(S))=\sum\limits_{T\subseteq ...

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

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

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

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

  10. UOJ#418. 【集训队作业2018】三角形

    #418. [集训队作业2018]三角形 和三角形没有关系 只要知道儿子放置的顺序,就可以直接模拟了 记录历史最大值 用一个pair(a,b):之后加上a个,期间最大值为增加b个 合并? A1+A2= ...

随机推荐

  1. Radius+OpenLdap+USG防火墙认证

    1.1.安装OpenLdap # 在数据目录创建ldap文件存放ldap的配置文件 mkdir -p /data/ldap/{data,conf} docker run -p 389:389 -p 6 ...

  2. 字符串小记 I:基本结构与简单匹配(更新中)

    0.一些定义 在开始之前,我们先给出一些关于字符串的定义: 记 \(|S|\) 表示字符串 \(S\) 的长度,\(S_i\) 表示该字符串中第 \(i\) 位的字符,\(S_{l,r}\) 表示该字 ...

  3. BFF层提升业务性能实际解决方案,以及nodeJs和KOA框架介绍

    本文干货满满,介绍了用BFF层(Back-end For Front-end)中间层提升性能的整体解决方案和思路,涉及前期技术调研,聚合业务分析,聚合方法,验收,最后向同学们普及node.koa基础知 ...

  4. QT(3)-QTableView

    @ 目录 0 相关文章 1 说明 2 常用函数 2.1 clearSpans 2.2 setSpan 2.3 columnAt 2.4 rowAt 2.5 columnSpan 2.6 rowSpan ...

  5. python代码签到学习同

    仅用于学习使用 import requests,json,time #填入Cookie headers={ "Cookie": "", "User-A ...

  6. linux操作系统读写文件操作(c语言)

    (一)open系统的调用 为了创建一个新的文件描述,需要使用系统调用open #include<fcntl.h> #include<sys/types.h> #include& ...

  7. 高性能队列——Disruptor(转)

    https://tech.meituan.com/disruptor.html 背景 Disruptor是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题(在性能测试中 ...

  8. Python 数据库应用教程:安装 MySQL 及使用 MySQL Connector

    Python可以用于数据库应用程序. 其中最流行的数据库之一是MySQL. MySQL数据库 为了能够在本教程中尝试代码示例,您应该在计算机上安装MySQL. 您可以在 MySQL官方网站 下载MyS ...

  9. Ubuntu 20.04 挂载 NTFS 硬盘 / 格式化并挂载 EXT4 硬盘

    创建挂载目录 mkdir /mnt/hdd 此目录在最后一步中用得到. 确定要挂载的硬盘 fdisk -l 由于我们要挂载的是 NTFS 硬盘,根据上面的信息,可以确定 /dev/sda1 是我们要挂 ...

  10. Android Recyclerview的item间距实现

    Recyclerview中,提供了一个方法addItemDecoration给我们用于设置item的分割线 下面提供几个常见的分割线效果 注: 下面的SizeUtils是AndroidUtilCode ...