BZOJ 3456 城市规划 ( NTT + 多项式求逆 )
题目链接:
https://www.lydsy.com/JudgeOnline/problem.php?id=3456
题意:
求出\(n\)个点的简单(无重边无自环)无向连通图的个数。(\(n<=130000\)).
并且输出方案数mod \(1004535809(479 * 2 ^ {21} + 1)\).
题解:
这题是POJ 1737的加强版。
从之前写过的题解中:
POJ 1737 Connected Graph
我们知道存在这样的递推式:
$$f[n]=2{C(n,2)}-\sum_{i=1}{n-1}f[i]C(n-1,i-1)2^{C(n-i,2)}$$
将上式左右两边同除以\((n−1)!\)得到:
$$\frac{f[n]}{(n−1)!}=\frac{2^{C(n,2)}}{(n−1)!} - \frac{\sum_{i=1}{n-1}f[i]*C(n-1,i-1)*2{C(n-i,2)}}{(n−1)!}$$
$$\implies \frac{f[n]}{(n−1)!}=\frac{2^{C(n,2)}}{(n−1)!} - \sum_{i=1}{n-1}\frac{f[i]*2{C(n-i,2)}}{(i-1)!*(n-i)!}$$
$$\implies \frac{2{C(n,2)}}{(n−1)!}=\sum_{i=1}{n}\frac{f[i]2^{C(n-i,2)}}{(i-1)!(n-i)!} $$
$$\implies \sum_{i=1}{n}\frac{f[i]}{(i-1)!}*\frac{2{C(n-i,2)}}{(n-i)!} = \frac{2^{C(n,2)}}{(n−1)!} $$
这个显然是一个卷积的形式。
指数级生成函数。
那么我们可以令:
$$A = \sum_{i=1}{n}\frac{f[i]}{(i-1)!}xi$$
$$B = \sum_{i=0}{n}\frac{2{C(i,2)}}{i!}x^i$$
$$C = \sum_{i=1}{n}\frac{2{C(i,2)}}{(i−1)!}x^i$$
有:
$$A*B = C$$
那么有:
$$A≡C*B{-1}(mod x{n+1})$$
先预处理\(B\)和\(C\),再用多项式求逆得到\(B\)的逆,再跑个NTT就可以了。
复杂度:\(O(nlogn)\).
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
const int maxLen = 18, maxm = 1 << maxLen | 1;
const ll maxv = 1e10 + 6; // 1e14, 1e15
const int N = 1000000;
const long double pi = acos(-1.0); // double maybe is not enough
ll mod = 1004535809, nlim, sp, msk;
ll qpower(ll x, ll p) { // x ^ p % mod
ll ret = 1;
while (p) {
if (p & 1) (ret *= x) %=mod;
(x *= x) %=mod;
p >>= 1;
}
return ret;
}
int R[N];
int G = 3;
void NTT(int *a,int f,int n,int L)
{
for(int i = 0;i < n; i++) {
R[i] = (R[i>>1]>>1)|((i&1)<<(L-1));
}
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 wn = qpower(G,(mod-1)/(i<<1));
if(f==-1) wn = qpower(wn,mod-2);
for(int j = 0;j < n;j += (i<<1))
{
int w=1;
for(int k = 0; k < i; k++,w = 1LL * w * wn % mod)
{
int x=a[j+k];
int y=1LL*a[j+k+i]*w%mod;
a[j+k]=(x+y)%mod;
a[j+k+i]=(x-y+mod)%mod;
}
}
}
if(f==-1){
int tmp = qpower(n,mod-2);
for(int i = 0;i < n;i++)
{
a[i] = 1LL * a[i] * tmp % mod;
}
}
}
int d[N];
void ployInv(int *a,int *b,int n,int L){
if(n == 1){
b[0] = qpower(a[0],mod - 2);return;
}
ployInv(a,b,n >> 1,L - 1);
memcpy(d,a,n*sizeof(int));
memset(d + n,0,n*sizeof(int));
NTT(d,1,n << 1,L + 1);
NTT(b,1,n << 1,L + 1);
for(int i = 0;i < (n<<1); i++) {
b[i] = 1LL * b[i] * ((2LL - 1LL * d[i] * b[i] % mod + mod) % mod) % mod;
}
NTT(b,-1,n << 1,L + 1);
memset(b + n,0,n * sizeof(int));
}
ll n,m;
ll fac[N];
int L;
int A[N],B[N],C[N],inv_B[N];
int main()
{
// freopen("in.txt","r",stdin);
std::cin >> n;
m = 1;
while(m <= (n << 1)) m<<=1, L++;
fac[0] = 1;
for(int i = 1; i <= n; i++) {
fac[i] = fac[i-1] * i % mod;
}
for(ll i = 0; i <= n; i++) {
B[i] = qpower(2,(i * (i - 1)>>1)) * qpower(fac[i],mod - 2) % mod;
}
for(ll i = 1; i <= n; i++) {
C[i] = qpower(2,(i * (i - 1)>>1)) * qpower(fac[i - 1],mod - 2) % mod;
}
A[0] = 1;
ployInv(B,inv_B,m,L);
NTT(inv_B,1,m,L);
NTT(C,1,m,L);
for(int i = 0; i < m; i++) {
A[i] = 1LL * inv_B[i] * C[i] % mod;
}
NTT(A,-1,m,L);
std::cout << A[n] * fac[n-1] % mod << '\n';
return 0;
}
BZOJ 3456 城市规划 ( NTT + 多项式求逆 )的更多相关文章
- BZOJ 3456: 城市规划 与 多项式求逆算法介绍(多项式求逆, dp)
题面 求有 \(n\) 个点的无向有标号连通图个数 . \((1 \le n \le 1.3 * 10^5)\) 题解 首先考虑 dp ... 直接算可行的方案数 , 容易算重复 . 我们用总方案数减 ...
- BZOJ 3456: 城市规划(dp+多项式求逆)
传送门 解题思路 这道题就是求带标号的无向连通图个数,首先考虑\(O(n^2)\)的做法,设\(f_i\)表示有\(i\)个节点的无向连通图个数,那么考虑容斥,先把所有的无向图求出,即为\(2^{C( ...
- 【BZOJ】3456: 城市规划 动态规划+多项式求逆
[题意]求n个点的带标号无向连通图个数 mod 1004535809.n<=130000. [算法]动态规划+多项式求逆 [题解]设$g_n$表示n个点的无向图个数,那么显然 $$g_n=2^{ ...
- 【bzoj3456】城市规划 容斥原理+NTT+多项式求逆
题目描述 求出n个点的简单(无重边无自环)无向连通图数目mod 1004535809(479 * 2 ^ 21 + 1). 输入 仅一行一个整数n(<=130000) 输出 仅一行一个整数, 为 ...
- 【BZOJ 3456】 3456: 城市规划 (NTT+多项式求逆)
3456: 城市规划 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 658 Solved: 364 Description 刚刚解决完电力网络的问题 ...
- 【BZOJ】3456: 城市规划(多项式求ln)
题解 在我写过分治NTT,多项式求逆之后 我又一次写了多项式求ln 我们定义一个数列的指数型生成函数为 \(\sum_{i = 0}^{n} \frac{A_{i}}{i!} x^{i}\) 然后这个 ...
- BZOJ 4555 [Tjoi2016&Heoi2016]求和 ——分治 NTT 多项式求逆
不想多说了,看网上的题解吧,我大概说下思路. 首先考察Stirling的意义,然后求出递推式,变成卷积的形式. 然后发现贡献是一定的,我们可以分治+NTT. 也可以直接求逆(我不会啊啊啊啊啊) #in ...
- [BZOJ3456]城市规划:DP+NTT+多项式求逆
写在前面的话 昨天听吕老板讲课,数数题感觉十分的神仙. 于是,ErkkiErkko这个小蒟蒻也要去学数数题了. 分析 Miskcoo orz 带标号无向连通图计数. \(f(x)\)表示\(x\)个点 ...
- BZOJ1042 HAOI2008硬币购物(任意模数NTT+多项式求逆+生成函数/容斥原理+动态规划)
第一眼生成函数.四个等比数列形式的多项式相乘,可以化成四个分式.其中分母部分是固定的,可以多项式求逆预处理出来.而分子部分由于项数很少,询问时2^4算一下贡献就好了.这个思路比较直观.只是常数巨大,以 ...
随机推荐
- 二 MapReduce 各阶段流程分析
如果想要将问题变得清晰.精准和优雅, 需要关注 MapReduce 作业所需要的系统资源,尤其是集群内部网络资源使用情况. MR 可以运行在共享集群上处理 TB 级 甚至 PB 级的数据.同时,改作业 ...
- 独立python环境之virtualenv和virtualenvwrapper
介绍 如果有一台測试机,多个人使用,有多个项目,不同项目可能python版本号不一样.须要的库不一样. 我们须要一个独立干净的python环境,互相隔离,互不影响. virtualenv能够帮我们解决 ...
- Struts2 全局结果集
1.index,jsp <body> Result类型 <ol> <li><a href="user/user?type=1">返回 ...
- 内联函数(Inline Functions)
影响性能的一个重要因素是内联技巧.内联函数也可称为内嵌函数. 在C++中,函数调用需要建立栈环境,进行参数复制,保护调用现场,返回时,还要进行返回值复制,恢复调用现场.这些工作都是与完成特定任务的操作 ...
- 威联通212P 在admin用户密码正确情况下仍然无法登录WEB页面解决办法
*登录 telnet 执行以下语句: [~] # cp /etc/default_config/passwd /mnt/HDA_ROOT/.config/passwd[~] # cp /etc/def ...
- Vue中对data的操作
1. {{a}} var vm = new Vue({ el: '#app', data: { a: { a: 1, b: 2 } } }) vm.a.c = 'sadoisad' // 按理说是 ...
- 【Docker自定制镜像之Dockerfile】
镜像的定制,就是定制每一层所添加的配置.文件,如果可以把每一层修改.安装.构建.操作的命令都写入到一个脚本中,用脚本来构建.定制镜像,这个脚本就是Dockerfile Dockerfile是一个文本文 ...
- Java并发包之CountDownLatch用法
CountDownLatch计数器闭锁是一个能阻塞主线程,让其他线程满足特定条件下主线程再继续执行的线程同步工具. Latch闭锁的意思,是一种同步的工具类.类似于一扇门:在闭锁到达结束状态之前,这扇 ...
- 洛谷—— P1328 生活大爆炸版石头剪刀布
https://www.luogu.org/problem/show?pid=1328 题目描述 石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头.如果两个人出拳一样,则不分胜负.在< ...
- azure云中 mount: wrong fs type, bad option, bad superblock on /dev/sdc1
2016-01-30 mount失败问题解决 [root@mofficedb2 ~]# mount /dev/sdc /dta mount: you must specify the filesyst ...