bzoj3456 城市规划

标签: bzoj
3人阅读 评论(0) 收藏 举报
分类:

Description


刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了.
刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得整个国家的任意两个城市都直接或间接的连通. 为了省钱, 每两个城市之间最多只能有一条直接的贸易路径. 对于两个建立路线的方案, 如果存在一个城市对, 在两个方案中是否建立路线不一样, 那么这两个方案就是不同的, 否则就是相同的. 现在你需要求出一共有多少不同的方案.
好了, 这就是困扰阿狸的问题. 换句话说, 你需要求出n个点的简单(无重边无自环)无向连通图数目.
由于这个数字可能非常大, 你只需要输出方案数mod 1004535809(479 * 2 ^ 21 + 1)即可.

方案数 mod 1004535809.
对于 100%的数据, n <= 130000

Solution


之前似乎做过求给定连通块数量的dp,这个也是类似吧
令f[i]表示i个点形成连通块的方案数,有f[i]=2C(i,2)j=1i1C(i1,j1)×f[j]×2C(ij,2)
大概就是容斥,总的方案数减去不符合的方案数,j用来枚举点1所在连通块的大小,剩下的随便连
我们令wn=2C(n,2),拆一下柿子可以发现f[i]=wij=1i1f[j]×(i1)!(j1)!×wij(ij)!
两边同时除(i-1)!得到f[i](i1)!=wi(i1)!j=1i1f[j](j1)!×wij(ij)!
移项得到wi(i1)!=j=1if[j](j1)!×wij(ij)!
分别令三坨东西为三个多项式A B C,得到A=BCB=AC1,求出多项式C(x)的逆元即可

多项式求逆:
假定我们已经求出了多项式A(x)在模xn2意义下的逆元多项式B(x),现在要求多项式A(x)在模xn意义下的逆元多项式G(x)
根据定义可得
A(x)B(x)1(modxn2)
A(x)G(x)1(modxn)
那么两式相减(考虑同余的性质,可以撕烤一下为什么是这样
B(x)G(x)0(modxn)
平方得到B2(x)+G2(x)2B(x)G(x)0(modxn)
左右同时乘A(x)得到G(x)2B(x)AB2(x)(modxn) 注意这里全部变成xn同余下了,只能消去此时的G(x)
这样就能用递归(or倍增 的方法搞定多项式求逆了,注意把多项式补齐为2的次幂项

Code


#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>

typedef long long LL;
const int MOD=1004535809;
const int N=300005;
const int g=3;

LL rev[N],tmp[N],fac[N],ny[N],a[N],c[N],nc[N];
LL nyn;

LL ksm(LL x,LL dep) {
    LL ret=1;
    while (dep) {
        if (dep&1) ret=ret*x%MOD;
        x=x*x%MOD; dep/=2;
    }
    return ret;
}

void NTT(LL *a,int len,int f) {
    int lg=log(len)/log(2)+0.1;
    for (int i=0;i<len;i++) {
        rev[i]=(rev[i/2]/2)|((i&1)<<(lg-1));
        if (i<rev[i]) std:: swap(a[i],a[rev[i]]);
    }
    for (int i=1;i<len;i*=2) {
        LL wn=ksm(g,(MOD-1)/i/2);
        if (f==-1) wn=ksm(g,(MOD-1)-(MOD-1)/i/2);
        for (int j=0;j<len;j+=i*2) {
            LL w=1;
            for (int k=0;k<i;k++) {
                int u=a[j+k],v=a[j+i+k]*w%MOD;
                a[j+k]=(u+v)%MOD; a[j+i+k]=(u-v+MOD)%MOD;
                w=wn*w%MOD;
            }
        }
    }
    if (f==-1) {
        LL nnyy=ksm(len,MOD-2);
        for (int i=0;i<len;i++) a[i]=a[i]*nnyy%MOD;
    }
}

void get_ny(LL *a,LL *b,int n) {
    if (n==1) {
        b[0]=ksm(a[0],MOD-2);
        return ;
    }
    get_ny(a,b,n/2);
    memcpy(tmp,a,sizeof(a[0])*n);
    memset(tmp+n,0,sizeof(tmp[0])*n);
    NTT(tmp,n*2,1); NTT(b,n*2,1);
    for (int i=0;i<n*2;i++) tmp[i]=((LL)b[i]%MOD*(2-tmp[i]*b[i]%MOD+MOD)%MOD)%MOD;
    NTT(tmp,n*2,-1);
    for (int i=0;i<n;i++) b[i]=tmp[i];
    memset(b+n,0,sizeof(b[0])*n);
}

int main(void) {
    int n; scanf("%d",&n);
    int len; for (len=1;len<=n;len*=2);
    fac[0]=ny[0]=1;
    for (int i=1;i<=n;i++) fac[i]=fac[i-1]*(LL)i%MOD,ny[i]=ksm(fac[i],MOD-2);
    for (int i=0;i<=n;i++) c[i]=ksm(2,((LL)(i-1)*i/2)%(MOD-1))*ny[i]%MOD;
    for (int i=1;i<=n;i++) a[i]=ksm(2,((LL)(i-1)*i/2)%(MOD-1))*ny[i-1]%MOD;
    get_ny(c,nc,len);
    NTT(a,len*2,1); NTT(nc,len*2,1);
    for (int i=0;i<len*2;i++) a[i]=a[i]*nc[i]%MOD;
    NTT(a,len*2,-1);
    printf("%lld\n", a[n]*fac[n-1]%MOD);
    return 0;
}
查看评论

BZOJ 3456 城市规划 快速傅里叶变换

题目大意:求nn个点的无向简单连通图个数,n≤1.3∗105n\leq1.3*10^5 递推式:fi=2C2i−∑i−1j=1fj∗Cj−1i−1∗2C2i−jf_i=2^{C_i^2}-\sum_...
  • PoPoQQQ
  • PoPoQQQ
  • 2015-05-27 17:08:39
  • 3458

[bzoj3456]城市规划

题目大意 给你n个点(存在顺序性),初始无边,你可以任意加边。求满足以下条件的连通图数量:无重边无自环。答案模479∗221+1479 * 2 ^{21} + 1 DP 我们设f[i]表示i个点...
  • WerKeyTom_FTD
  • WerKeyTom_FTD
  • 2015-12-23 20:31:28
  • 882

BZOJ 3456 城市规划

FNT
  • Fuxey
  • Fuxey
  • 2016-05-11 12:11:59
  • 878

BZOJ3456:城市规划(EGF+FFT/CDQ分治+FFT)

传送门题意:无向连通图的计数。题解: dalao的题解:http://blog.miskcoo.com/2015/05/bzoj-3456我说说做题时遇到的坑点吧: 1.C(i,2)不能用阶乘逆元...
  • qq_35649707
  • qq_35649707
  • 2017-11-29 22:42:18
  • 183

bzoj-3456 城市规划

题意: 求n个点的无向连通图个数; n个点不同,答案对1004535809取模; n 题解: 生成函数的种种神奇应用; 不过这玩意真是越来越不OI了(笑); 这道题首先考虑递推公式; 设f[x]为...
  • ww140142
  • ww140142
  • 2015-09-13 14:22:34
  • 1399

BZOJ 3456 城市规划 多项式求ln

BZOJ 3456 城市规划 多项式求ln
  • wzq_QwQ
  • wzq_QwQ
  • 2015-09-14 10:05:22
  • 1831

bzoj3456 城市规划(分治NTT)

bzoj3456 城市规划 原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3456 题意: 阿狸的国家有n个城市, 现在国家需要在某...
  • Bfk_zr
  • Bfk_zr
  • 2018-02-04 09:09:00
  • 122

Bzoj3456:城市规划:NTT

题目链接:城市规划 设g[i]表示i个点的连通图的个数,h[i]表示i个点的图有多少个 有 容斥一下,假设有j个点组成了合法的图,剩下的i-j个点不合法,那么新图不合法 有 组合数拆掉,等式...
  • qq_34025203
  • qq_34025203
  • 2016-06-17 07:49:49
  • 521

bzoj 3456: 城市规划 (NTT+多项式求逆)

题目描述传送门题目大意:求n个点简单无向连通图数,其中任意点之间可以随意连边,不存在重边和自环。题解设f[n]f[n]表示n个点简单连通图个数(即1所属的连通块内有n个点) f[n]=2(n−1)∗...
  • clover_hxy
  • clover_hxy
  • 2017-02-24 11:40:00
  • 653

bzoj3456/jzoj3303:城市规划(画柿子+多项式逆元+NTT)

我noip初赛最后半个小时就在数4个点的连通图有几个,结果还数错了…然后我就很膜拜这题,终于被我在jzoj找到了。 权限题传送门 题意:n个不同的点的构成的连通图有多少种,模一个费马素数。n≤2e...
  • q582116859
  • q582116859
  • 2017-10-25 20:03:49
  • 153
    个人资料
    持之以恒
    等级:
    访问量: 12万+
    积分: 8161
    排名: 3147
    乱七八糟
    文章分类
    最新评论