1. 程式人生 > >bzoj 3456 城市規劃

bzoj 3456 城市規劃

就是直接EGF求ln即可。 EGF參見這篇部落格

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define N 1600010
#define p 1004535809
#define clr(a,n) memset(a,0,sizeof(int)*(n))
#define cpy(a,b,n) memcpy(a,b,sizeof(int)*(n))
#define gc getchar()
#define debug(x) cerr<<#x<<"="<<x #define sp <<" " #define ln <<endl using namespace std; inline int inn() { int x,ch;while((ch=gc)<'0'||ch>'9'); x=ch^'0';while((ch=gc)>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^'0');return x; } inline
int fast_pow(int x,lint k,int ans=1) { for(;k;k>>=1,x=(lint)x*x%p) (k&1)?ans=(lint)ans*x%p:0;return ans; } int h[N],f[N]; namespace NTT_space{ int h[N],t[N],r[N],A1[N],A2[N]; inline int NTT(int *a,int n,int s) { for(int i=1;i<n;i++) if(i<r[i]) swap(a[i],a[r[i]])
; for(int i=2;i<=n;i<<=1) { int wn=fast_pow(3,(s>0)?(p-1)/i:p-1-(p-1)/i); for(int j=0,t=i>>1;j<n;j+=i) for(int k=0,w=1;k<t;k++,w=(lint)w*wn%p) { int x=a[j+k],y=(lint)w*a[j+k+t]%p; a[j+k]=(x+y)%p,a[j+k+t]=(x-y+p)%p; } } int ninv=fast_pow(n,p-2); if(s<0) rep(i,0,n-1) a[i]=(lint)a[i]*ninv%p; return 0; } inline int tms(int *a,int *b,int *c,int n,int m)//c=ab,a[n]=b[m]=0 { int k=1,L=0;while(k<n+m) k<<=1,L++; rep(i,1,k-1) r[i]=(r[i>>1]>>1)|((i&1)<<(L-1)); clr(A1,k),cpy(A1,a,n),NTT(A1,k,1), clr(A2,k),cpy(A2,b,m),NTT(A2,k,1); rep(i,0,k-1) c[i]=(lint)A1[i]*A2[i]%p; return NTT(c,k,-1); } inline int tms(int *a,int *b,int *c,int n) { return tms(a,b,c,n,n); } inline int polyinv(int *a,int *inv,int m) { int n=1;while(n<=m) n<<=1; clr(inv,n),inv[0]=fast_pow(a[0],p-2); for(int i=2;i<=n;i<<=1) { cpy(h,inv,i);rep(j,0,i-1) h[j]=2ll*h[j],(h[j]>=p?h[j]-=p:0); tms(inv,inv,inv,i>>1),tms(inv,a,inv,i); rep(j,0,i-1) inv[j]=h[j]-inv[j],(inv[j]<0?inv[j]+=p:0); clr(inv+i,i); } return 0; } inline int polydif(int *a,int *b,int n) { b[n]=0;rep(i,0,n-1) b[i]=(i+1ll)*a[i+1]%p;return 0; } inline int polyint(int *a,int *b,int n) { b[0]=0;rep(i,1,n) b[i]=(lint)a[i-1]*fast_pow(i,p-2)%p;return 0; } inline int polyln(int *a,int *pln,int n) { return polyinv(a,pln,n),polydif(a,h,n),tms(pln,h,h,n),polyint(h,pln,n); } inline int polyexp(int *a,int *e,int m) { int n=1;while(n<=m*2) n<<=1; clr(e,n),e[0]=1; for(int i=2;i<=n;i<<=1) { polyln(e,t,i>>1); for(int j=0;j<(i>>1);j++) t[j]=(a[j]-t[j]+(j==0)+p)%p; tms(e,t,e,i>>1),clr(e+i,i); } return 0; } } using NTT_space::tms; using NTT_space::polyinv; using NTT_space::polyln; using NTT_space::polydif; using NTT_space::polyint; using NTT_space::polyexp; int fac[N],facinv[N]; inline int prelude(int n) { rep(i,fac[0]=1,n) fac[i]=(lint)fac[i-1]*i%p; facinv[n]=fast_pow(fac[n],p-2); for(int i=n-1;i>=0;i--) facinv[i]=(i+1ll)*facinv[i+1]%p; return 0; } int main() { int n=inn();prelude(n+1); rep(i,0,n+1) h[i]=(lint)fast_pow(2,i*(i-1ll)/2)*facinv[i]%p; return polyln(h,f,n+1),!printf("%d\n",int((lint)f[n]*fac[n]%p)); }