BZOJ3456: 城市规划
Description
刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了.
刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得整个国家的任意两个城市都直接或间接的连通. 为了省钱, 每两个城市之间最多只能有一条直接的贸易路径. 对于两个建立路线的方案, 如果存在一个城市对, 在两个方案中是否建立路线不一样, 那么这两个方案就是不同的, 否则就是相同的. 现在你需要求出一共有多少不同的方案.
好了, 这就是困扰阿狸的问题. 换句话说, 你需要求出n个点的简单(无重边无自环)无向连通图数目.
由于这个数字可能非常大, 你只需要输出方案数mod 1004535809(479 * 2 ^ 21 + 1)即可.
Input
仅一行一个整数n(<=130000)
Output
仅一行一个整数, 为方案数 mod 1004535809.
Sample Input
Sample Output
HINT
对于 100%的数据, n <= 130000
#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
inline int read() {
int x=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
const int maxn=132000;
const int G=3;
const int p=1004535809;
typedef long long ll;
ll pow(ll n,ll m,ll mod=p) {
ll ans=1;
for(;m;m>>=1,(n*=n)%=mod) if(m&1) (ans*=n)%=p;
return ans;
}
ll wn[20];
void NTT(ll* A,int len,int tp) {
int j=len>>1,c=0;
rep(i,1,len-2) {
if(i<j) swap(A[i],A[j]);int k=len>>1;
while(j>=k) j-=k,k>>=1;j+=k;
}
for(int i=2;i<=len;i<<=1) {
c++;
for(int j=0;j<len;j+=i) {
ll w=1;
for(int k=j;k<j+(i>>1);k++) {
ll u=A[k],t=w*A[k+(i>>1)]%p;
A[k]=(u+t)%p;A[k+(i>>1)]=(u-t+p)%p;
w=(w*wn[c])%p;
}
}
}
if(tp<0) {
ll inv=pow(len,p-2);
rep(i,1,len/2-1) swap(A[i],A[len-i]);
rep(i,0,len-1) A[i]=(A[i]*inv)%p;
}
}
ll xp[maxn],inv[maxn];
ll f[maxn],T[maxn],A[maxn],B[maxn];
void solve(int l,int r) {
if(l==r) return;
int mid=l+r>>1,len=1;solve(l,mid);
while(len<=(max(mid-l+1,r-mid)<<1)) len<<=1;
rep(i,0,len-1) A[i]=B[i]=0;
rep(i,l,mid) A[i-l]=f[i]*inv[i-1]%p;
rep(i,1,r-l) B[i]=inv[i]*T[i]%p;
NTT(A,len,1);NTT(B,len,1);
rep(i,0,len-1) A[i]=(A[i]*B[i])%p;
NTT(A,len,-1);
rep(i,mid+1,r) f[i]=((f[i]-xp[i-1]*A[i-l])%p+p)%p;
solve(mid+1,r);
}
int main() {
xp[0]=inv[0]=1;int n=read();
rep(i,1,19) wn[i]=pow(G,(p-1)/(1<<i));
rep(i,1,n) xp[i]=(xp[i-1]*i)%p,inv[i]=pow(xp[i],p-2),f[i]=T[i]=pow(2,(ll)i*(i-1)/2);
solve(1,n);printf("%lld\n",f[n]);
return 0;
}
(UPD)从Po姐那里学来了O(NlogN)的多项式逆元做法。
本题题解:http://blog.csdn.net/popoqqq/article/details/46049331
多项式逆元:http://picks.logdown.com/posts/189620-the-inverse-element-of-polynomial%20%E8%B7%AApicks%E5%A4%A7%E6%AF%92%E7%98%A4
#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
inline int read() {
int x=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
typedef long long ll;
const int p=1004535809;
const int G=3;
const int maxn=270000;
ll wn[20];
ll pow(ll n,ll m,ll mod=p) {
ll ans=1;
for(;m;m>>=1,(n*=n)%=mod) if(m&1) (ans*=n)%=mod;
return ans;
}
void NTT(ll* A,int len,int tp) {
int j=len>>1,c=0;
rep(i,1,len-2) {
if(i<j) swap(A[i],A[j]);int k=len>>1;
while(j>=k) j-=k,k>>=1;j+=k;
}
for(int i=2;i<=len;i<<=1) {
c++;
for(int j=0;j<len;j+=i) {
ll w=1;
for(int k=j;k<j+(i>>1);k++) {
ll u=A[k],v=w*A[k+(i>>1)]%p;
A[k]=(u+v)%p;A[k+(i>>1)]=(u-v+p)%p;
w=(w*wn[c])%p;
}
}
}
if(tp<0) {
ll inv=pow(len,p-2);
rep(i,1,len/2-1) swap(A[i],A[len-i]);
rep(i,0,len-1) (A[i]*=inv)%=p;
}
}
ll tmp[maxn];
void getinv(ll* A,ll* B,int n) {
if(n==1) {B[0]=pow(A[0],p-2);return;}
getinv(A,B,n>>1);
rep(i,0,n-1) tmp[i]=A[i],tmp[i+n]=0;
NTT(B,n<<1,1);NTT(tmp,n<<1,1);
rep(i,0,(n<<1)-1) tmp[i]=(2-tmp[i]*B[i]%p+p)%p;
rep(i,0,(n<<1)-1) (B[i]*=tmp[i])%=p;
NTT(B,n<<1,-1);
rep(i,n,(n<<1)-1) B[i]=0;
}
ll A[maxn],B[maxn],C[maxn],B2[maxn];
ll xp[maxn],invxp[maxn],xp2[maxn];
int main() {
rep(i,0,19) wn[i]=pow(G,(p-1)/(1<<i));
int n=read(),len=1;while(len<=(n<<1))len<<=1;
xp[0]=invxp[0]=xp2[0]=1;
rep(i,1,n) xp2[i]=pow(2,(ll)i*(i-1)/2),xp[i]=(xp[i-1]*i)%p,invxp[i]=pow(xp[i],p-2);
rep(i,0,n) B[i]=xp2[i]*invxp[i]%p;
rep(i,1,n) C[i]=xp2[i]*invxp[i-1]%p;
getinv(B,B2,len>>1);
NTT(B2,len,1);NTT(C,len,1);
rep(i,0,len-1) A[i]=(B2[i]*C[i])%p;
NTT(A,len,-1);
printf("%lld\n",A[n]*xp[n-1]%p);
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城市规划
题目描述 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了.刚才说过, 阿狸的国家有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( ...
随机推荐
- SQL中的多表查询,以及JOIN的顺序重要么?
说法是,一般来说,JOIN的顺序不重要,除非你要自己定制driving table. 示例: SELECT a.account_id, c.fed_id, e.fname, e.lname -> ...
- poj 1006:Biorhythms(水题,经典题,中国剩余定理)
Biorhythms Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 110991 Accepted: 34541 Des ...
- javascript实用技巧,js小知识
一.js整数的操作 使用|0和~~可以将浮点转成整型且效率方面要比同类的parseInt,Math.round 要快,在处理像素及动画位移等效果的时候会很有用.性能比较见此. var foo = (1 ...
- HTML5+CSS3的响应式网页设计:自动适应屏幕宽度
这几天都在修改博客上面的样式.本来用的是d83.0的模板.自己又修改了许多地方,其中自己修改的一些地方在手机里面显示的效果不是很理想,于是想改成自适应的效果.对CSS3不是特别的熟练,只能去网上找找案 ...
- SSIS 包单元测试检查列表
1. 使用脚本任务(Script tasks) 组建的时候,在日志里增加一些调试信息,例如变量更新信息,可以帮助我们从日志中查看到变量是在何时何地更新的. 2. 使用ForceExecutionRes ...
- wordpress源码解析-目录结构-文件调用关系(1)
学习开源代码,是一种很快的提升自己的学习方法.Wordpress作为一个开源的博客系统,非常优秀,应用广泛,使用起来简单方便,具有丰富的主题和插件,可以按照自己的需求来任意的进行修改.所以就从word ...
- 为什么没有选择sipml5
转自:http://www.myvoipapp.com/blogs/yxh/2015/01/23/%E4%B8%BA%E4%BB%80%E4%B9%88%E6%B2%A1%E6%9C%89%E9%80 ...
- JDK中的设计模式
Creational(创建模式) Abstract factory: 创建一组有关联的对象实例.这个模式在JDK中也是相当的常见,还有很多的framework例如Spring.我们很容易找到这样的实例 ...
- 在Eclipse中用图形界面的方式获取Salesforce中Object的Query语句
对Salesforce中的Object进行相应的Query是必不可少的操作,大家可以去这个链接去看看官网的解读 http://docs.database.com/dbcom/en-us/db_sos ...
- LoadRunner 脚本学习 -- 指针基础
先搞清楚 ++a 和 a++的区别 ++a : 前缀++, 先自增,后表达式 a++ : 后缀++, 先表达式,后自增 前缀,自增立即生效. 后缀,下次才会看到效果. 一维数组的指针 Action ...