【BZOJ3456】城市规划
题目
思路&算法
我们设点数为\(n\)的简单图的数量为\(f_n\), 点数为\(n\)的简单连通图有\(g_i\)个
于是我们知道,从\(n\)个点中选\(2\)个点有\(n \choose 2\)种选法, 而对于两个点可以连边或不连, 于是\(f_n = 2^{n \choose 2}\)
同时, \(f_n\)还满足\(f_n = \sum\limits_{i = 1}^{n}{n-1 \choose {i-1}}g_if_{n-i}\), 因为我们可以考虑钦定某一点为联通块中的一点, 然后从剩余的点中找\(i-1\)个点, 练成一个联通块, 剩下随便, 然后\(i\)取遍\(1 \sim n\)中的所有数后的和为\(f_n\)。
于是, 我们来愉快的推式子
\]
把\(f_n = 2^{n \choose 2}\)带入
2^{n \choose 2} &= \sum_{i = 1}^{n}{{n-1} \choose {i-1}}2^{{n-i\;} \choose {2}}g_i\\
2^{n \choose 2} &= \sum_{i = 1}^{n}\frac{{(n-1)!}/{(i-1)!}}{(n-i)!}g_i2^{{n-i\;} \choose 2}\\
2^{n \choose 2} &= \sum_{i = 1}^{n}\frac{{(n-1)!}}{(n-i)!(i-1)!}g_i2^{{n-i\;} \choose {2}}\\
2^{n \choose 2} &= (n-1)!\sum_{i = 1}^{n}\frac{1}{(i-1)!(n-i)!}g_i2^{{n-i\;} \choose {2}}\\
\frac{2^{{n} \choose 2}}{(n-1)!} &= \sum_{i=1}^{n}\frac{1}{(n-i)!(n-1)!}g_i2^{{n-i\;} \choose {2}}\\
\frac{2^{{n} \choose 2}}{(n-1)!} &= \sum_{i=1}^{n} \left(\frac{1}{n-i}2^{{n-i\;} \choose {2}}\right)\left(\frac{1}{(i-1)!}g_i\right)
\end{align*}
\]
这是一个卷积
我们令
\(A(x) = \sum\limits_{i = 1}^{n}\frac{1}{(i-1)!}2^{i \choose 2}x^i\), \(B(x) = \sum\limits_{i = 1}^{n}\frac{1}{(i-1)!}g_{i-1}x^i\), \(C(x) = \sum\limits_{i = 0}^{n-1}\frac{1}{i!}2^{i \choose 2}x^i\)
于是\(C(x) = A(x)B(x)\)
然后\(B(x) = A(x)C^{-1}(x)\)
代码
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 520010;
const LL mod = 1004535809LL;
inline LL power(LL a, LL n, LL mod)
{ LL Ans = 1;
a %= mod;
while (n)
{ if (n & 1) Ans = (Ans * a) % mod;
a = (a * a) % mod;
n >>= 1;
}
return Ans;
}
struct Mul
{ int rev[N];
int Len, Bit;
LL wn[N];
void getReverse()
{ for (int i = 0; i < Len; i++)
rev[i] = (rev[i>>1] >> 1) | ((i&1) * (Len >> 1));
}
void NTT(LL * a, int opt)
{ getReverse();
for (int i = 0; i < Len; i++)
if (i < rev[i]) swap(a[i], a[rev[i]]);
int cnt = 0;
for (int i = 2; i <= Len; i <<= 1)
{ cnt++;
for (int j = 0; j < Len; j += i)
{ LL w = 1LL;
for (int k = 0; k < (i>>1); k++)
{ LL x = a[j + k];
LL y = (w * a[j + k + (i>>1)]) % mod;
a[j + k] = (x + y) % mod;
a[j + k + (i>>1)] = (x - y + mod) % mod;
w = (w * wn[cnt]) % mod;
}
}
}
if (opt == -1)
{ reverse(a + 1, a + Len);
LL num = power(Len, mod-2, mod);
for (int i = 0; i < Len; i++)
a[i] = (a[i] * num) % mod;
}
}
void getLen(int l)
{ Len = 1, Bit = 0;
for (; Len <= l; Len <<= 1) Bit++;
}
void init()
{ for (int i = 0; i < 22; i++)
wn[i] = power(3, (mod-1) / (1LL << i), mod);
}
} Calc;
LL tmp1[N], tmp2[N];
void cpy(LL * A, LL * B, int len1, int len2)
{ for (int i = 0; i < len1; i++) A[i] = B[i];
for (int i = len1; i < len2; i++) A[i] = 0;
}
void getInv(LL * A, LL * B, int Len)
{ B[0] = power(A[0], mod-2, mod);
for (register int i = 2; i <= Len; i <<= 1)
{ int l = i << 1;
cpy(tmp1, A, i, l);
cpy(tmp2, B, i>>1, l);
Calc.Len = l;
Calc.NTT(tmp1, 1);
Calc.NTT(tmp2, 1);
for (register int j = 0; j < l; j++)
tmp1[j] = ((2LL * tmp2[j]) % mod + mod - ((tmp2[j] * tmp2[j]) % mod * tmp1[j]) % mod) % mod;
Calc.NTT(tmp1, -1);
for (register int j = 0; j < i; j++)
B[j] = tmp1[j];
}
}
LL A[N], B[N], Ans[N];
LL fac[N];
int main()
{ int n;
scanf("%d", &n);
fac[0] = 1;
for (int i = 1; i <= n; i++)
fac[i] = (fac[i-1] * (LL) i) % mod;
Calc.getLen(n);
int len = Calc.Len;
Calc.init();
A[0] = 1;
for (int i = 1; i < n; i++)
A[i] = (power(2LL, (LL) i * (LL) (i-1) / 2LL, mod) * power(fac[i], mod-2, mod)) % mod;
B[0] = 0;
for (int i = 1; i <= n; i++)
B[i] = (power(2LL, (LL) i * (LL) (i-1) / 2LL, mod) * power(fac[i-1], mod-2, mod)) % mod;
getInv(A, Ans, len);
Calc.Len = len << 1;
Calc.NTT(Ans, 1);
Calc.NTT(B, 1);
for (int i = 0; i < Calc.Len; i++)
Ans[i] = (Ans[i] * B[i]) % mod;
Calc.NTT(Ans, -1);
printf("%lld\n", (Ans[n] * fac[n-1]) % mod);
return 0;
}
【BZOJ3456】城市规划的更多相关文章
- [BZOJ3456]城市规划(生成函数+多项式求逆+多项式求ln)
城市规划 时间限制:40s 空间限制:256MB 题目描述 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了. 刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一 ...
- BZOJ3456 城市规划 【多项式求ln】
题目链接 BZOJ3456 题解 真是一道经典好题,至此已经写了分治\(NTT\),多项式求逆,多项式求\(ln\)三种写法 我们发现我们要求的是大小为\(n\)无向联通图的数量 而\(n\)个点的无 ...
- BZOJ3456 城市规划(多项式求逆)
设f[i]为连通图的数量,g[i]为不连通图的数量,显然有f[i]=2i*(i-1)/2-g[i],g[i]通过枚举1所在连通块大小转移,有g[i]=Σf[j]*C(i-1,j-1)·2(i-j)*( ...
- BZOJ3456 城市规划 【多项式求逆】
题目链接 BZOJ3456 题解 之前我们用分治\(ntt\)在\(O(nlog^2n)\)的复杂度下做了这题,今天我们使用多项式求逆 设\(f_n\)表示\(n\)个点带标号无向连通图数 设\(g_ ...
- BZOJ3456 城市规划 【分治NTT】
题目链接 BZOJ3456 题解 据说这题是多项式求逆 我太弱不会QAQ,只能\(O(nlog^2n)\)分治\(NTT\) 设\(f[i]\)表示\(i\)个节点的简单无向连通图的数量 考虑转移,直 ...
- BZOJ3456: 城市规划
Description 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了. 刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得整个国家的任意两个城市都直接或 ...
- BZOJ3456城市规划
题目描述 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了.刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得整个国家的任意两个城市都直接或间接的连通.为了 ...
- BZOJ3456 城市规划 【生成函数】【FFT】
题目分析: 容易想到生成函数的构造方法. 令g(n)表示n个点的无向图个数,f(n)表示n个点的无向连通图的个数.式子是显然的. 容易发现式子是卷积的形式,写出生成函数,然后多项式求逆后多项式乘法即可 ...
- 2019.01.03 bzoj3456: 城市规划(生成函数+多项式取对)
传送门 生成函数好题. 题意:求n个点的简单(无重边无自环)无向连通图数目 思路: 对简单无向图构造生成函数f(x)=∑n2Cn2xnn!f(x)=\sum_n2^{C_n^2}\frac{x^n}{ ...
- bzoj3456 城市规划 多项式求In
\(n\)个点的无向联通图的个数 打着好累啊 一定要封装一个板子 记\(C(x)\)为无向图个数的指数型生成函数,\(C(0) = 1\) 记\(G(x)\)为无向联通图个数的指数型生成函数,\(G( ...
随机推荐
- Python学习【第7篇】:Python之常用模块2
hashlib,configparser,logging模块 一.常用模块二 hashlib模块 hashlib提供了常见的摘要算法,如md5和sha1等等. 那么什么是摘要算法呢?摘要算法又称为哈希 ...
- ES6学习历程(变量的解构赋值)
一.数组的解构赋值 1.举几个例子足以理解 let [a, b, c] = [1, 2, 3]; a:1; b:2; c:3; let [x, , y] = [1, 2, 3]; x:1 y ...
- C++ 中 字符数组 和 指针 区别
char str1[] = "abc"; char str2[] = "abc"; const char str3[] = "abc"; c ...
- UID中RUID、EUID和SUID的区别
看UNIX相关的书时经常能遇到这几个概念,但一直没有好好去理清这几个概念,以致对这几个概念一直一知半解.今天好好区分了一下这几个概念并总结如下.说白了这几个UID引出都是为了系统的权限管理. 下面分别 ...
- 手撸HashMap实现
前言 HashMap是Java中常用的集合,而且HashMap的一些思想,对于我们平时解决业务上的一些问题,在思路上有帮助,基于此,本篇博客将分析HashMap底层设计思想,并手写一个迷你版的Hash ...
- 非常简单的Python HTTP服务
如果你急需一个简单的Web Server,但你又不想去下载并安装那些复杂的HTTP服务程序,比如:Apache,ISS等.那么, Python 可能帮助你.使用Python可以完成一个简单的内建 HT ...
- hadoop balancer
一.balancer是当hdfs集群中一些datanodes的存储要写满了或者有空白的新节点加入集群时,用于均衡hdfs集群磁盘使用量的一个工具.这个工具作为一个应用部署在集群中,可以由集群管理员在一 ...
- Html学习总结(2)——Html页面head标签元素的意义和应用场景
相信在html5之前,很少人会关注html页面上head里标签元素的定义和应用场景,可能记得住的只有"title"."keyword"和"descri ...
- HTML5:去除IE10中输入框和密码框的X按钮和小眼睛
在IE10和之后的IE版本中,当在输入框和密码框中输入的时候,后面会自动出现X按钮和小眼睛,如下图所示: 令人苦恼的是,这个效果只有IE才有,其它浏览器是没有这个功能的.为了统一,我们就需要去掉这个 ...
- pthread_rwlock pthread读写锁
原文: http://www.cnblogs.com/diegodu/p/3890450.html 使用读写锁 配置读写锁的属性之后,即可初始化读写锁.以下函数用于初始化或销毁读写锁.锁定或解除锁定读 ...