【BZOJ-3456】城市规划 CDQ分治 + NTT
题目链接
http://www.lydsy.com/JudgeOnline/problem.php?id=3456
Solution
这个问题可以考虑dp,利用补集思想
N个点的简单图总数量为$2^{\binom{N}{2}}$,要求的是简单联通图,所以可以用总量减不连通的。
不连通的可以通过枚举与某个固定点的联通的点的数量得到$tot=\sum _{i=1} ^{N} \binom{N-1}{i-1}*dp[i]*2^{\binom{N-i}{2}}$
其中$dp[i]$表示的就是$i$个点的联通图数量。
然后将公式稍稍变型整理成$\frac{dp[N]}{(N-1)!}=\frac{2^{\binom{N}{2}}}{(N-1)!}-\sum_{i=1}^{N-1}\frac{dp[i]}{(i-1)!}*\frac{2^{\binom{N-i}{2}}}{(N-i)!}$
这个式子可以利用 CDQ分治+NTT 在$O(Nlog^{2}N)$的时间得到。
至于这道题吗,显然是可以多项式求逆来做的,复杂度$O(NlnN)$,上述做法自己写的被卡常了,不过本机效果还不错,留下代码以后看看。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define LL long long #define P 1004535809LL
#define G 3LL #define MAXN 800010 int N,len; inline LL Pow(LL x,LL y) {LL re=1; for (LL i=y; i; i>>=1,x=x*x%P) if (i&1) re=re*x%P; return re;} inline LL Inv(LL x) {return Pow(x,P-2);} int A[MAXN],B[MAXN],ans[MAXN],wn[31],dp[MAXN]; inline void Rader(int *x)
{
for (register int i=1,j=len>>1,k; i<len-1; i++) {
if (i<j) swap(x[i],x[j]);
k=len>>1;
while (j>=k) j-=k,k>>=1;
if (j<k) j+=k;
}
} inline void DFT(int *x,int opt)
{
Rader(x);
for (register int h=2,id=0; h<=len; h<<=1) {
LL Wn=wn[++id];
for (register int i=0; i<len; i+=h) {
LL W=1;
for (register int j=i; j<i+h/2; j++) {
LL u=(LL)x[j]%P,t=(LL)W*x[j+h/2]%P;
x[j]=(u+t)%P; x[j+h/2]=(u-t+P)%P;
W=W*Wn%P;
}
}
}
if (opt==-1) {
for (register int i=1; i<len/2; i++) swap(x[i],x[len-i]);
for (register int i=0; i<len; i++) x[i]=(LL)x[i]*Inv(len)%P;
}
} inline void NTT()
{
DFT(A,1); DFT(B,1);
for (register int i=0; i<len; i++) ans[i]=(LL)A[i]*B[i]%P;
DFT(ans,-1);
} int C2[MAXN],fac[MAXN],ifac[MAXN]; inline void CDQ(int l,int r)
{
if (l==r) {
dp[l]=(C2[l]-(LL)dp[l]*fac[l-1]%P+P)%P; return;
}
int mid=(l+r)>>1; CDQ(l,mid); for (register int i=l; i<=mid; i++) A[i-l]=(LL)dp[i]*ifac[i-1]%P;
for (register int i=0; i<=r-l; i++) B[i]=(LL)C2[i]*ifac[i]%P;
for (register int i=mid-l+1; i<=r-l; i++) A[i]=0;
len=1; while (len<((r-l+1)<<1)) len<<=1;
for (register int i=r-l+1; i<len; i++) A[i]=B[i]=0;
NTT();
for (register int i=mid+1; i<=r; i++) (dp[i]+=ans[i-l])%=P; CDQ(mid+1,r);
} int main()
{
// freopen("count.in","r",stdin);
// freopen("count.out","w",stdout); scanf("%d",&N); for (register int i=0; i<=30; i++) wn[i]=Pow(G,(P-1)/(1<<i)); fac[0]=ifac[0]=1;
for (register int i=1; i<=N; i++) fac[i]=((LL)fac[i-1]*i)%P,ifac[i]=Inv(fac[i]); for (register int i=1; i<=N; i++) C2[i]=Pow(2LL,(LL)((LL)i*(i-1))/2); CDQ(1,N); printf("%d\n",dp[N]); return 0;
}
【BZOJ-3456】城市规划 CDQ分治 + NTT的更多相关文章
- [BZOJ 3456]城市规划(cdq分治+FFT)
[BZOJ 3456]城市规划(cdq分治+FFT) 题面 求有标号n个点无向连通图数目. 分析 设\(f(i)\)表示\(i\)个点组成的无向连通图数量,\(g(i)\)表示\(i\)个点的图的数量 ...
- [BZOJ 2989]数列(CDQ 分治+曼哈顿距离与切比雪夫距离的转化)
[BZOJ 2989]数列(CDQ 分治) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]| ...
- BZOJ 3456: 城市规划 与 多项式求逆算法介绍(多项式求逆, dp)
题面 求有 \(n\) 个点的无向有标号连通图个数 . \((1 \le n \le 1.3 * 10^5)\) 题解 首先考虑 dp ... 直接算可行的方案数 , 容易算重复 . 我们用总方案数减 ...
- HDU5322 Hope(DP + CDQ分治 + NTT)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5322 Description Hope is a good thing, which can ...
- BZOJ 3456: 城市规划 [多项式求逆元 组合数学 | 生成函数 多项式求ln]
3456: 城市规划 题意:n个点组成的无向连通图个数 以前做过,今天复习一下 令\(f[n]\)为n个点的无向连通图个数 n个点的完全图个数为\(2^{\binom{n}{2}}\) 和Bell数的 ...
- bzoj 4237 稻草人 - CDQ分治 - 单调栈
题目传送门 传送点I 传送点II 题目大意 平面上有$n$个点.问存在多少个矩形使得只有左下角和右上角有点. 考虑枚举左下角这个点.然后看一下是个什么情况: 嗯对,是个单调栈.但不可能暴力去求每个点右 ...
- bzoj 3262 陌上花开 - CDQ分治 - 树状数组
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...
- BZOJ4555求和(cdq分治+NTT)
题意: 输出f(n)对998244353(7 × 17 × 223 + 1)取模的结果.1 ≤ n ≤ 100000 其中S(i,j)是第二类Stirling数,即有i个球,丢到j个盒子中,要求盒子不 ...
- BZOJ 3456 城市规划 (组合计数、DP、FFT)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3456 著名的多项式练习题,做法也很多,终于切掉了纪念 首先求一波递推式: 令\(F(n ...
随机推荐
- .NET面试题系列(四)计算机硬件知识
计算机的硬件组成 总线:贯穿整个系统的是一组电子管道(其实就是传输数据的线路),也就是总线.总线传送的是字,字的大小与系统相关,比如在32位操作系统当中, 一个字是4个字节. I/O设备:I/O设备是 ...
- .net中的一般处理程序实例
最近在学习一般处理程序,也学习了一些jQuery的异步操作,于是就想着亲手做一个小的登陆,锻炼一下自己. 1.首先新建了一个项目LoginDemo,在此基础上又添加了一个一般处理程序BackLogin ...
- [python]python错误集锦
ValueError: invalid literal : ''不能将非数字字符串转换为整型 object has no attribute 对象调用一个没有的方法(内建或自定义) TypeError ...
- 20155325 2016-2017-2 《Java程序设计》第8周学习总结
教材学习内容总结 NIO用于高级输入/输出处理 名称 衔接数据源与目的地 IO InputStream,OutputStream NIO Channel 类 方法 方法的作用 ReadableByte ...
- 20155210潘滢昊 2016-2017-2 《Java程序设计》第6周学习总结
20155210 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 流(Stream)是对「输入输出」的抽象,注意「输入输出」是相对程序而言的 InputStr ...
- codeforces 235 div2 A. Vanya and Cards
Vanya loves playing. He even has a special set of cards to play with. Each card has a single integer ...
- Hive笔记之宏(macro)
一.啥是宏 宏可以看做是一个简短的函数,或者是对一个表达式取别名,同时可以将这个表达式中的一些值做成变量调用时传入,比较适合于做分析时为一些临时需要用到很多次的表达式操作封装一下取个简短点的别名来调用 ...
- Ubuntu下ibus在firefox浏览器中选中即删除的解决办法
Ubuntu上的firefox更新到36版后,ibus在浏览器中输入中文时选中的文字就会被删除.这个问题在很多贴吧.论坛上也有讨论,不过很多方法都无效.最简单有效的办法就是在命令行输入 ibus-se ...
- keepalived启动不成功,状态一直是inactive(dead) 的解决办法以及keepalived高版本没有rc.d目录,虚拟VIP无法访问问题
安装配置教程我就不说了,网上很多,这里只给出我遇到的两个坑: 1 rc.d目录 ,kp在1.4版本之后rc.d要去解压之后的源码包里去找,make之后的目录里面没有了,我使用的是2.0.13最新版本, ...
- .NET下获取应用程序目录的一些方法
今天在Console Application下搞了一个小功能,期间需要获取当前应用程序的根目录,试了很多方式,都不能直接获取到,没有像Server.MapPath()这类的方法来方便地使用. 下面列举 ...