题目链接

BZOJ3456

题解

之前我们用分治\(ntt\)在\(O(nlog^2n)\)的复杂度下做了这题,今天我们使用多项式求逆

设\(f_n\)表示\(n\)个点带标号无向连通图数

设\(g_n\)表示\(n\)个点图的数量,显然\(g_n = 2^{{n \choose 2}}\)

枚举\(1\)号点所在联通块大小,我们有

\[g_n = \sum\limits_{i = 1}^{n} {n - 1 \choose i - 1}f_{i}g_{n - i}
\]

代入\(g_n\)

\[2^{{n \choose 2}} = \sum\limits_{i = 1}^{n} \frac{(n - 1)!}{(n - i)!(i - 1)!}f_{i}2^{{n - i \choose 2}}
\]

整理一下:

\[\frac{2^{{n \choose 2}}}{(n - 1)!} = \sum\limits_{i = 1}^{n} \frac{f_i}{(i - 1)!} * \frac{2^{{n - i \choose 2}}}{(n - i)!}
\]

发现是一个卷积的形式

\[F(x) = \sum\limits_{n = 1}^{+\infty} \frac{f_n}{(n - 1)!} x^n
\]

\[G(x) = \sum\limits_{n = 0}^{+\infty} \frac{2^{{n \choose 2}}}{n!} x^n
\]

\[H(x) = \sum\limits_{n = 1}^{+\infty} \frac{2^{{n \choose 2}}}{(n - 1)!} x^n
\]

则有

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

那么

\[F(x) = H(x)G^{-1}(x)
\]

多项式求逆后再求一次卷积就可求得答案

复杂度\(O(nlogn)\),快了不少

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 300005,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
const int G = 3,P = 1004535809;
int f[maxn],g[maxn],h[maxn],gv[maxn],N;
int fac[maxn],inv[maxn],fv[maxn];
int c[maxn],R[maxn];
inline int qpow(int a,LL b){
int re = 1;
for (; b; b >>= 1,a = 1ll * a * a % P)
if (b & 1) re = 1ll * re * a % P;
return re;
}
void NTT(int* a,int n,int f){
for (int i = 0; i < n; i++) if (i < R[i]) swap(a[i],a[R[i]]);
for (int i = 1; i < n; i <<= 1){
int gn = qpow(G,(P - 1) / (i << 1));
for (int j = 0; j < n; j += (i << 1)){
int g = 1,x,y;
for (int k = 0; k < i; k++,g = 1ll * g * gn % P){
x = a[j + k]; y = 1ll * g * a[j + k + i] % P;
a[j + k] = (x + y) % P; a[j + k + i] = ((x - y) % P + P) % P;
}
}
}
if (f == 1) return;
int nv = qpow(n,P - 2); reverse(a + 1,a + n);
for (int i = 0; i < n; i++) a[i] = 1ll * a[i] * nv % P;
}
void work(int deg,int* a,int* b){
if (deg == 1){b[0] = qpow(a[0],P - 2); return;}
work((deg + 1) >> 1,a,b);
int L = 0,n = 1;
while (n < (deg << 1)) n <<= 1,L++;
for (int i = 1; i < n; i++) R[i] = (R[i >> 1] >> 1) | ((i & 1) << (L - 1));
for (int i = 0; i < deg; i++) c[i] = a[i];
for (int i = deg; i < n; i++) c[i] = 0;
NTT(c,n,1); NTT(b,n,1);
for (int i = 0; i < n; i++)
b[i] = 1ll * ((2ll - 1ll * c[i] * b[i] % P) % P + P) % P * b[i] % P;
NTT(b,n,-1);
for (int i = deg; i < n; i++) b[i] = 0;
}
void init(){
fac[0] = fac[1] = inv[0] = inv[1] = fv[0] = fv[1] = 1;
for (int i = 2; i <= N; i++){
fac[i] = 1ll * fac[i - 1] * i % P;
inv[i] = 1ll * (P - P / i) * inv[P % i] % P;
fv[i] = 1ll * fv[i - 1] * inv[i] % P;
}
g[0] = 1;
for (int i = 1; i <= N; i++){
h[i] = 1ll * qpow(2,1ll * i * (i - 1) / 2) * fv[i - 1] % P;
g[i] = 1ll * qpow(2,1ll * i * (i - 1) / 2) * fv[i] % P;
}
}
int main(){
N = read();
init();
work(N + 1,g,gv);
int L = 0,n = 1;
while (n <= (N << 1)) n <<= 1,L++;
for (int i = 1; i < n; i++) R[i] = (R[i >> 1] >> 1) | ((i & 1) << (L - 1));
NTT(h,n,1); NTT(gv,n,1);
for (int i = 0; i < n; i++)
f[i] = 1ll * h[i] * gv[i] % P;
NTT(f,n,-1);
int ans = 1ll * f[N] * fac[N - 1] % P;
printf("%d\n",ans);
return 0;
}

BZOJ3456 城市规划 【多项式求逆】的更多相关文章

  1. BZOJ 3456: 城市规划 多项式求逆

    Description 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了.  刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得整个国家的任意两个城市都直接 ...

  2. 【BZOJ3456】城市规划 多项式求逆

    [BZOJ3456]城市规划 Description 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了. 刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得 ...

  3. bzoj 3456 城市规划 多项式求逆+分治FFT

    城市规划 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1091  Solved: 629[Submit][Status][Discuss] Desc ...

  4. bzoj3456 城市规划 多项式求In

    \(n\)个点的无向联通图的个数 打着好累啊 一定要封装一个板子 记\(C(x)\)为无向图个数的指数型生成函数,\(C(0) = 1\) 记\(G(x)\)为无向联通图个数的指数型生成函数,\(G( ...

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

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

  6. 【bzoj3456】城市规划(多项式求逆+dp)

    Description 求\(~n~\)个点组成的有标号无向连通图的个数.\(~1 \leq n \leq 13 \times 10 ^ 4~\). Solution 这道题的弱化版是poj1737, ...

  7. 【bzoj3456】城市规划 容斥原理+NTT+多项式求逆

    题目描述 求出n个点的简单(无重边无自环)无向连通图数目mod 1004535809(479 * 2 ^ 21 + 1). 输入 仅一行一个整数n(<=130000) 输出 仅一行一个整数, 为 ...

  8. [bzoj3456] 城市规划 [递推+多项式求逆]

    题面 bzoj权限题面 离线题面 思路 orz Miskcoo ! 先考虑怎么算这个图的数量 设$f(i)$表示$i$个点的联通有标号无向图个数,$g(i)$表示$n$个点的有标号无向图个数(可以不连 ...

  9. [BZOJ3456]城市规划:DP+NTT+多项式求逆

    写在前面的话 昨天听吕老板讲课,数数题感觉十分的神仙. 于是,ErkkiErkko这个小蒟蒻也要去学数数题了. 分析 Miskcoo orz 带标号无向连通图计数. \(f(x)\)表示\(x\)个点 ...

随机推荐

  1. Angular : 基础语句说明, 响应式表单指令, 组件生命周期钩子

  2. 强化记忆之php

    php 输出的区分 新手摸索道路,有说不对的地方,还请多多包涵. echo 能够输出一个以上的字符串,也能输出html标签 print  一次只能接受一个字符串(区分与echo),也能输出html标签 ...

  3. 《史上最简单的MySQL教程》系列分享专栏

    <史上最简单的MySQL教程>系列分享专栏 <史上最简单的MySQL教程>已整理成PDF文档,点击可直接下载至本地查阅https://www.webfalse.com/read ...

  4. R语言学习笔记(十五):获取文件和目录信息

    file.info() 参数是表示文件名称的字符串向量,函数会给出每个文件的大小.创建时间.是否为目录等信息. > file.info("z.txt") size isdir ...

  5. SpringMVC接收前端传值有哪些方式?

    有很多种,比如: 1.通过@RequestParam注解接收请求参数: 2.通过Bean封装,接收多个请求参数 3.通过@ModelAttribute绑定接收前端表单数据 4.通过@PathVaria ...

  6. 使用maven插件生成grpc所需要的Java代码

    1.首先需要编写自己需要的.proto文件,本文重点不在这里,.proto可以参考grpc官方例子 https://grpc.io/docs/quickstart/java.html 2.创建自己的J ...

  7. 人工智能,图片识别,与GUI编程

    GUI编程: https://sourceforge.net/projects/pyqt/ 百度aip图片识别 https://pypi.python.org/pypi/baidu-aip

  8. Apache 服务器性能评估

    1 查看当前并发连接数 netstat -an | grep ESTABLISHED | wc -l 2 查看当前进程数 ps aux|grep httpd|wc -l

  9. Qt 飞机仪表显示

    使用Qt简单谢了一个飞机的一小部分仪表,还没有写完,目前只写了一个界面,不过思想应该是一样的. 效果图如下 其中主要由转速表,和下面的部分数字显示构成 转速表代码 .h文件 #ifndef CONTR ...

  10. 自动化测试--封装getDriver的方法

    在自动化测试的时候,通常都会把最常用的功能封装起来,实现通用性. 该篇博客是实现了getDriver方法的封装. 第一次封装的时候,是使用的传参. @Parameters(value = {" ...