• Bzoj3456 城市规划


    Time Limit: 40 Sec  Memory Limit: 256 MB
    Submit: 681  Solved: 383

    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

    Source

    POJ1737 Connected Graph 的升级版

    在上面那道题中可以得到基本的递推公式 $ F[i]=2^C_{n}^{2} − sum_{j=1}^{i-1} (C(i-1,j-1)*F[j]*2^C_{i-j}^{2} $

    数学问题 动态规划 NTT 生成函数 多项式求逆

    蒟蒻自带大常数,TLE简直无情

    经过了一番艰苦卓绝的优化,可算是过了。

    懒得贴公式了,留坑日后填

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstdio>
      4 #include<cstring>
      5 #define LL long long
      6 using namespace std;
      7 const LL mod=1004535809;
      8 const int G=3;
      9 const int mxn=1000007;
     10 int ansksm[mxn];
     11 int ksm(LL a,LL k){
     12     if(a==3 && k<mxn && ansksm[k])return ansksm[k];
     13     int tmp=k;
     14     LL res=1;a%=mod;
     15     while(k){
     16         if(k&1)res=(res*a)%mod;
     17         a=a*a%mod;
     18         k>>=1;
     19     }
     20     if(a==3)ansksm[tmp]=res;
     21     return res;
     22 }
     23 LL fac[mxn],inv[mxn];
     24 void init(int mxn){
     25     fac[0]=fac[1]=1;
     26     inv[0]=inv[1]=1;
     27     for(int i=2;i<mxn;i++){
     28         fac[i]=i*fac[i-1]%mod;
     29         inv[i]=((-mod/i*inv[mod%i])%mod+mod)%mod;
     30     }
     31     for(int i=2;i<mxn;i++)inv[i]=inv[i]*inv[i-1]%mod;
     32     return;
     33 }
     34 //
     35 int wn[mxn],wr[mxn];
     36 int N,len,rev[mxn];
     37 void NTT(LL *a,int flag){
     38     int i,j,k;
     39     for(i=0;i<N;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
     40     for(i=1;i<N;i<<=1){
     41         int p=i<<1;
     42 //        LL gn=ksm(G,(flag==1)?(mod-1)/p:(mod-1)-(mod-1)/p);
     43         int gn;gn=(flag==1)?wn[i]:gn=wr[i];
     44         for(j=0;j<N;j+=p){
     45             LL g=1;
     46             for(k=0;k<i;k++,g=g*gn%mod){
     47                 int x=a[j+k],y=g*a[j+k+i]%mod;
     48                 a[j+k]=x+y;if(a[j+k]>mod)a[j+k]-=mod;
     49                 a[j+k+i]=x-y;if(a[j+k+i]<0)a[j+k+i]+=mod;
     50             }
     51         }
     52     }
     53     if(flag==-1){
     54         LL INV=ksm(N,mod-2);
     55         for(i=0;i<N;i++)a[i]=a[i]*INV%mod;
     56     }
     57     return;
     58 }
     59 //
     60 LL a[mxn],b[mxn],c[mxn];
     61 void Get_inv(int n,LL *a){
     62     if(n==1){b[0]=1;return;}
     63     Get_inv((n+1)>>1,a);
     64 //    printf("Get %d
    ",n);
     65     int m=n,i;
     66     for(N=1,len=0;N<=m;N<<=1)len++;
     67     for(i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1));
     68     for(i=0;i<n;i++)c[i]=a[i];    
     69     for(register int i=n;i<N;i++)c[i]=0;
     70     NTT(c,1);NTT(b,1);
     71     for(i=0;i<N;i++){
     72         b[i]=(2-(LL)c[i]*b[i]%mod)*b[i]%mod;
     73         if(b[i]<0)b[i]+=mod;
     74     }
     75     NTT(b,-1);
     76     for(i=n;i<N;i++)b[i]=0;
     77     return;
     78 }
     79 int n;
     80 int main(){
     81 //    freopen("in.txt","r",stdin);
     82     int i,j;
     83     scanf("%d",&n);
     84     int ed=n*2;
     85     init(ed+1);
     86     for (int i=1;i<=ed;i<<=1){
     87         wn[i]=ksm(3,(mod-1)/(i<<1));
     88         wr[i]=ksm(3,(mod-1)-(mod-1)/(i<<1));
     89     }
     90     int m=n;
     91     for(N=1,len=0;N<=m;N<<=1)len++;
     92     a[0]=1;
     93     for(i=1;i<=n;i++)a[i]=ksm(2,((LL)i*(i-1)/2)%(mod-1))*inv[i]%mod;
     94     Get_inv(N,a);
     95     for(N=1,len=0;N<=m;N<<=1)len++;
     96     for(i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1));
     97     for(i=1;i<=n;i++)c[i]=ksm(2,(LL)i*(i-1)/2%(mod-1))*inv[i-1]%mod;
     98     c[0]=0;for(i=n+1;i<N;i++)c[i]=0;
     99     NTT(b,1);NTT(c,1);
    100     for(i=0;i<N;i++)b[i]=b[i]*c[i]%mod;
    101     NTT(b,-1);
    102     printf("%lld
    ",b[n]*fac[n-1]%mod);
    103     return 0;
    104 }
  • 相关阅读:
    网线 ------ 交叉线
    ubuntu ------ 网络 ifconfig 不显示IP地址
    STM32L011D4 ----- 低功耗
    List 集合 使用 remove 踩得坑
    Map 集合遍历的4种方法
    elasticsearch 集群详解
    谷歌浏览器添加插件时显示程序包无效:"CRX_HEADER_INVALID" 解决办法
    MySql数据库 优化
    MySql 索引
    Kibana 安装
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6793527.html
Copyright © 2020-2023  润新知