设为首页 加入收藏

TOP

BZOJ 3456 城市规划 快速傅里叶变换
2015-11-21 01:00:52 来源: 作者: 【 】 浏览:1
Tags:BZOJ 3456 城市规划 快速 傅里叶 变换

题目大意:求 n 个点的无向简单连通图个数, n≤1.3?105
递推式: fi=2C2i?∑i?1j=1fj?Cj?1i?1?2C2i?j
推导戳这里
然后两侧同除 (i?1)! 得到:
fi(i?1)!=2C2i(i?1)!?∑i?1j=1fj?2C2i?j(j?1)!?(i?j)!

∑ij=1fj?2C2i?j(j?1)!?(i?j)!=2C2i(i?1)!

∑ij=1fj(j?1)!?2C2i?j(i?j)!=2C2i(i?1)!

这显然是一个卷积的形式

然后我们令:
A=∑ni=1fi(i?1)!xi
B=∑ni=02C2ii!xi
C=∑ni=12C2i(i?1)!xi
那么有 A?B=C
然后有 A≡C?B?1(mod xn+1)
多项式求逆搞一搞就好了
没想到还真有人的FFT比我还慢2333

#include 
   
     #include 
    
      #include 
     
       #include 
      
        #define M 263000 #define MOD 1004535809 #define G 3 using namespace std; int n,m; long long Quick_Power(long long x,long long y) { long long re=1; while(y) { if(y&1) (re*=x)%=MOD; (x*=x)%=MOD; y>>=1; } return re; } void FFT(int a[],int n,int type) { static int temp[M]; int i; if(n==1) return ; for(i=0;i
       
        >1]=a[i],temp[i+n>>1]=a[i+1]; memcpy(a,temp,sizeof(a[0])*n); int *l=a,*r=a+(n>>1); FFT(l,n>>1,type);FFT(r,n>>1,type); long long w=Quick_Power(G,(long long)(MOD-1)/n*type%(MOD-1)),wn=1; for(i=0;i
        
         >1;i++,(wn*=w)%=MOD) temp[i]=(l[i]+wn*r[i])%MOD,temp[i+(n>>1)]=(l[i]-wn*r[i]%MOD+MOD)%MOD; memcpy(a,temp,sizeof(a[0])*n); } void Get_Inv(int a[],int b[],int n) { static int temp[M]; int i; if(n==1) { b[0]=Quick_Power(a[0],MOD-2); return ; } Get_Inv(a,b,n>>1); memcpy(temp,a,sizeof(a[0])*n); memset(temp+n,0,sizeof(a[0])*n); FFT(temp,n<<1,1); FFT(b,n<<1,1); for(i=0;i
         
          >n; for(m=1;m<=n;m<<=1); for(fac[0]=1,i=1;i<=n;i++) fac[i]=fac[i-1]*i%MOD; for(i=0;i<=n;i++) B[i]=Quick_Power(2,((long long)i*(i-1)>>1)%(MOD-1))*Quick_Power(fac[i],MOD-2)%MOD; for(i=1;i<=n;i++) C[i]=Quick_Power(2,((long long)i*(i-1)>>1)%(MOD-1))*Quick_Power(fac[i-1],MOD-2)%MOD; Get_Inv(B,inv_B,m); FFT(inv_B,m<<1,1); FFT(C,m<<1,1); for(i=0;i
          
         
        
       
      
     
    
   
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇poj 1324 Holedox Moving A*算法.. 下一篇[LeetCode] Maximum Subarray

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: