首页 > 代码库 > Bzoj2629 binomial

Bzoj2629 binomial

 

Time Limit: 30 Sec  Memory Limit: 128 MB
Submit: 68  Solved: 32

Description

对于给定的n和p,求对于所有的0<=i<p,满足C(n,k)%p=i的k的个数
  注:C(n,k)=n!/(k!*(n-k)!)

Input

仅一行包含两个正整数n和p

Output

仅一行,为一个长度为p的字符串s,s[i]表示C(n,k)%p=i的k的个数除以29后的余数,s[i]视为一个29进制的数字

Sample Input

20 4

Sample Output

D440

HINT

 

n<p^10 p=51061

 

Source

 

动态规划  FFT

 

题解留坑待填

 

  1 #include<iostream>  2 #include<algorithm>  3 #include<cstring>  4 #include<cstdio>  5 #include<cmath>  6 #define LL long long  7 using namespace std;  8 const double pi=acos(-1.0);  9 const int mod=29; 10 const int P=51061; 11 const int ED=P-1; 12 const int mxn=150005; 13 int read(){ 14     int x=0,f=1;char ch=getchar(); 15     while(ch<0 || ch>9){if(ch==-)f=-1;ch=getchar();} 16     while(ch>=0 && ch<=9){x=x*10+ch-0;ch=getchar();} 17     return x*f; 18 } 19 int fac[mxn],inv[mxn]; 20 void init(){ 21     fac[0]=fac[1]=1;inv[0]=inv[1]=1; 22     for(int i=2;i<mxn;i++){ 23         fac[i]=(LL)fac[i-1]*i%P; 24         inv[i]=((-P/i*(LL)inv[P%i]%P)+P)%P; 25     } 26     for(int i=2;i<mxn;i++) 27         inv[i]=(LL)inv[i-1]*inv[i]%P; 28     return; 29 } 30 // 31 struct com{ 32     double x,y; 33     com(){} 34     com(double _x,double _y):x(_x),y(_y){} 35     com operator + (const com &b){return com(x+b.x,y+b.y);} 36     com operator - (const com &b){return com(x-b.x,y-b.y);} 37     com operator * (const com &b){return com(x*b.x-y*b.y,x*b.y+y*b.x);} 38     com operator / (const double v){return com(x/v,y/v);} 39 }A[mxn],B[mxn]; 40 int N,len,rev[mxn]; 41 void FFT(com *a,int flag){ 42     for(int i=0;i<N;i++)if(i<rev[i])swap(a[i],a[rev[i]]); 43     for(int i=1;i<N;i<<=1){ 44         int p=i<<1; 45         com wn=com(cos(pi/i),flag*sin(pi/i)); 46         for(int j=0;j<N;j+=p){ 47             com w=com(1,0); 48             for(int k=0;k<i;k++,w=w*wn){ 49                 com x=a[j+k],y=w*a[j+k+i]; 50                 a[j+k]=x+y; 51                 a[j+k+i]=x-y; 52             } 53         } 54     } 55     if(flag==-1) 56         for(int i=0;i<N;i++) a[i].x/=N; 57     return; 58 } 59 int C(int n,int m){ 60     if(n<m)return 0; 61     return (LL)fac[n]*inv[m]%P*inv[n-m]%P; 62 } 63 int pw[mxn],ind[mxn]; 64 int f[mxn]; 65 bool flag=0; 66 void solve(int x){ 67 //    printf("x:%d\n",x); 68     memset(B,0,sizeof B); 69     for(int i=0;i<=x;i++) 70         B[ind[C(x,i)]].x++; 71     for(int i=0;i<ED;i++){ 72         A[i].x=f[i]%mod;A[i].y=0; 73         B[i].x=((int)B[i].x)%mod; 74     } 75     for(int i=ED;i<N;i++)A[i].x=A[i].y=0; 76     FFT(A,1);FFT(B,1); 77     for(int i=0;i<N;i++)A[i]=A[i]*B[i]; 78     FFT(A,-1); 79     memset(f,0,sizeof f); 80     for(int i=0;i<N;i++){ 81         (f[i%ED]+=(int)(A[i].x+0.5)%mod)%=mod; 82     } 83     return; 84 } 85 char s[mxn]; 86 int num[mxn]; 87 int ans[mxn]; 88 int main(){ 89     int i,j; 90     init(); 91     pw[0]=1; 92     for(i=1;i<ED;i++)pw[i]=pw[i-1]*2%P; 93     for(i=0;i<ED;i++)ind[pw[i]]=i; 94     // 95     int m=P<<1; 96     for(N=1,len=0;N<=m;N<<=1)len++; 97     for(i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1)); 98     scanf("%s",s+1); 99     int len=strlen(s+1);100     for(i=1;i<=len;i++){101         num[i]=s[len-i+1]-0;102         ans[0]=(ans[0]*10+(s[i]-0))%mod;103     }104     ans[0]=(ans[0]+1)%mod;105     f[0]=1;106     while(len){107         num[0]=0;108         for(i=len;i;i--)num[i-1]+=num[i]%P*10,num[i]/=P;109         while(len && !num[len])len--;110         solve(num[0]/10);111     }112     for(i=0;i<ED;i++)ans[pw[i]]=f[i]%mod;113     for(i=1;i<P;i++){114         ans[0]=(ans[0]-ans[i])%mod;115     }116     ans[0]=(ans[0]+mod)%mod;117     for(i=0;i<P;i++){118         if(ans[i]>9)putchar(A+ans[i]-10);119             else putchar(0+ans[i]);120     }121     return 0;122 }

 

Bzoj2629 binomial