zoukankan      html  css  js  c++  java
  • bzoj 3456 城市规划 多项式求逆+分治FFT

    城市规划

    Time Limit: 40 Sec  Memory Limit: 256 MB
    Submit: 1091  Solved: 629
    [Submit][Status][Discuss]

    Description

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

    Input

     仅一行一个整数n(<=130000)
     

    Output

     仅一行一个整数, 为方案数 mod 1004535809.
     

    Sample Input

    3

    Sample Output

    4

    HINT

     对于 100%的数据, n <= 130000

    题解:http://blog.miskcoo.com/2015/05/bzoj-3456

        我没什么好说的。

      1 #include<cstring>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<iostream>
      5 #include<algorithm>
      6 
      7 #define ll long long
      8 #define N 262144
      9 #define mod 1004535809
     10 using namespace std;
     11 inline int read()
     12 {
     13     int x=0,f=1;char ch=getchar();
     14     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
     15     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
     16     return x*f;
     17 }
     18 
     19 int n;
     20 ll Factor[N],Inv_Fac[N];
     21 ll G[N],inv_fac[N],dao_G[N];
     22 int rev[N];
     23 
     24 ll fast_pow(ll x,ll y,ll MOD)
     25 {
     26     ll ret=1;
     27     while(y)
     28     {
     29         if(y&1)ret=(ret*x)%MOD;
     30         x=(x*x)%MOD;
     31         y>>=1;
     32     }
     33     return ret;
     34 }
     35 void init()
     36 {
     37     Factor[0]=1,Inv_Fac[0]=1;
     38     for(int i=1;i<=n;i++)
     39     {
     40         Factor[i]=Factor[i-1]*i%mod;
     41         Inv_Fac[i]=fast_pow(Factor[i],mod-2,mod);
     42     }
     43 }
     44 void NTT(ll *a,int num,int f)
     45 {
     46     for (int i=0;i<num;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
     47     for (int i=1;i<num;i<<=1)
     48     {
     49         ll wn=fast_pow(3,(mod-1)/(i<<1),mod);
     50         for(int j=0;j<num;j+=(i<<1))
     51         {
     52             ll w=1;
     53             for (int k=0;k<i;(w*=wn)%=mod,k++)
     54             {
     55                 ll x=a[j+k],y=w*a[j+k+i]%mod;
     56                 a[j+k]=(x+y>=mod)?x+y-mod:x+y;a[j+k+i]=(x-y<0)?x-y+mod:x-y;
     57             }
     58         }
     59     }
     60     if(f==-1)
     61     {
     62         for (int i=1;i<num/2;i++)swap(a[i],a[num-i]);
     63         ll inv=fast_pow(num,mod-2,mod);
     64         for (int i=0;i<num;i++)(a[i]*=inv)%=mod;
     65     }
     66 }
     67 void Get_Inv(ll *a,ll *b,int n)
     68 {
     69     static ll temp[N];
     70     if(n==1)
     71     {
     72         b[0]=fast_pow(a[0],mod-2,mod);
     73         return ;
     74     }
     75     Get_Inv(a,b,n>>1);
     76     memcpy(temp,a,sizeof(a[0])*n);
     77     memset(temp+n,0,sizeof(a[0])*n);
     78     int m=n,L=0,nn=n;
     79     for(n=1;n<=m;n<<=1)L++;if (L) L--;
     80     for(int i=0;i<n;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<L);
     81     NTT(temp,n,1),NTT(b,n,1);
     82     for(int i=0;i<n;i++)
     83         temp[i]=b[i]*(((2ll-temp[i]*b[i]%mod)%mod+mod)%mod)%mod;
     84     NTT(temp,n,-1);
     85     for(int i=0;i<(n>>1);i++)b[i]=temp[i];
     86     memset(b+nn,0,sizeof(b[0])*nn);
     87 }
     88 int main()
     89 {
     90     n=read(),init();
     91     for(int i=0;i<=n;i++)
     92     {
     93         if(i<2)G[i]=1;
     94         else G[i]=fast_pow(2,(ll)i*(i-1)/2,mod)*Inv_Fac[i]%mod;
     95     }
     96     for(int i=1;i<=n;i++) dao_G[i-1]=G[i]*i%mod;dao_G[n]=0;
     97     int l;for(l=1;l<=n;l<<=1);
     98     Get_Inv(G,inv_fac,l);
     99     int m=n,L=0;
    100     for(n=1;n<=m;n<<=1)L++;if (L) L--;
    101     for(int i=0;i<n;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<L);
    102     NTT(dao_G,n,1),NTT(inv_fac,n,1);
    103     for(int i=0;i<n;i++)
    104         dao_G[i]=(inv_fac[i]*dao_G[i])%mod;
    105     NTT(dao_G,n,-1);
    106     printf("%lld
    ",(dao_G[m-1]*fast_pow(m,mod-2,mod)%mod)*Factor[m]%mod);
    107 }
  • 相关阅读:
    Unity3D实践系列08, MonoBehaviour类的各种触发事件
    Unity3D实践系列07,组件的启用或禁用开关,物体的的可见或不可见开关,以及相应事件
    Unity3D实践系列06,球体撞击物体游戏
    Linux tee的花式用法和pee
    bash内置命令mapfile:读取文件内容到数组
    Perl正则表达式引用
    Perl文件句柄引用
    透明代理、正向代理、反向代理的区别说明
    Perl回调函数和闭包
    一文搞懂:词法作用域、动态作用域、回调函数、闭包
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8682048.html
Copyright © 2011-2022 走看看