题意题解不说了,这里主要讲用C++大数
为了节省时间使用了进制压缩,使用long long数组,进制1e9,使进制的平方在long long范围内
1290ms 4836KB
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const long long mod=1000000000; struct biginteger { long long number[26]; int len; biginteger operator+(biginteger &b) { int i,root=max(len,b.len),Len=1; biginteger ans; memset(ans.number,0,sizeof(ans.number)); ans.len=1; for(i=0; i<root||ans.number[i]; i++) { ans.number[i]+=number[i]+b.number[i]; if(ans.number[i]>=mod) { ans.number[i+1]+=ans.number[i]/mod; ans.number[i]%=mod; } if(ans.number[i]) Len=i; } ans.len=Len+1; return ans; } biginteger operator-(biginteger &b) { int i,root=max(len,b.len),Len=0; biginteger ans; memset(ans.number,0,sizeof(ans.number)); ans.len=1; for(i=0; i<root; i++) { ans.number[i]+=number[i]-b.number[i]; if(ans.number[i]<0) { ans.number[i+1]-=1; ans.number[i]+=mod; } if(ans.number[i]) Len=i; } ans.len=Len+1; return ans; } biginteger operator*(biginteger &b) { int i,j,root=0; biginteger ans; memset(ans.number,0,sizeof(ans.number)); ans.len=1; for(i=0; i<len; i++) { for(j=0; j<b.len; j++) ans.number[i+j]+=number[i]*b.number[j]; } for(i=0; i<=len+b.len||ans.number[i]; i++) { if(ans.number[i]>=mod) { ans.number[i+1]+=ans.number[i]/mod; ans.number[i]%=mod; } if(ans.number[i]) root=i; } ans.len=root+1; return ans; } bool Greater(biginteger b) { if(len>b.len) return true; if(len<b.len) return false; int i; for(i=len-1; i>=0; i--) { if(number[i]>b.number[i]) return true; if(number[i]<b.number[i]) return false; } return true; } biginteger operator/(biginteger &b) { biginteger ans_quotient; biginteger ans_remainder; memset(ans_quotient.number,0,sizeof(ans_quotient.number)); ans_quotient.len=1; memset(ans_remainder.number,0,sizeof(ans_remainder.number)); ans_remainder.len=1; biginteger temp; int i,j,root=0; long long w,head=0,l,r,mid; for(i=len-1; i>=b.len-1; i--) { head*=mod; head+=number[i]; l=head/(b.number[b.len-1]+1); r=head/b.number[b.len-1]; while(l<=r) { mid=(l+r)/2; memset(temp.number,0,sizeof(temp.number)); temp.len=1; temp.number[i-b.len+1]=mid; temp.len=i-b.len+2; temp=temp*b; if(Greater(temp)) l=mid+1; else r=mid-1; } w=max(r,(long long)0); memset(temp.number,0,sizeof(temp.number)); temp.len=1; temp.number[i-b.len+1]=w; temp.len=i-b.len+2; temp=temp*b; int xroot=max(len,temp.len); for(j=0; j<xroot; j++) { number[j]-=temp.number[j]; if(number[j]<0) { number[j+1]-=1; number[j]+=mod; } if(number[j]) len=j+1; } ans_quotient.number[i-b.len+1]=w; head=number[i]; if(root==0&&w!=0) root=i-b.len+2; } ans_quotient.len=max(root,1); for(i=0; i<len; i++) ans_remainder.number[i]=number[i]; ans_remainder.len=1; for(i=len-1; i>=0; i--) { if(ans_remainder.number[i]) { ans_remainder.len=i+1; break; } } return ans_quotient; } biginteger operator%(biginteger &b) { biginteger ans_quotient; biginteger ans_remainder; memset(ans_quotient.number,0,sizeof(ans_quotient.number)); ans_quotient.len=1; memset(ans_remainder.number,0,sizeof(ans_remainder.number)); ans_remainder.len=1; biginteger temp; int i,j,root=0; long long w,head=0,l,r,mid; for(i=len-1; i>=b.len-1; i--) { head*=mod; head+=number[i]; l=head/(b.number[b.len-1]+1); r=head/b.number[b.len-1]; while(l<=r) { mid=(l+r)/2; memset(temp.number,0,sizeof(temp.number)); temp.len=1; temp.number[i-b.len+1]=mid; temp.len=i-b.len+2; temp=temp*b; if(Greater(temp)) l=mid+1; else r=mid-1; } w=max(r,(long long)0); memset(temp.number,0,sizeof(temp.number)); temp.len=1; temp.number[i-b.len+1]=w; temp.len=i-b.len+2; temp=temp*b; int xroot=max(len,temp.len); for(j=0; j<xroot; j++) { number[j]-=temp.number[j]; if(number[j]<0) { number[j+1]-=1; number[j]+=mod; } if(number[j]) len=j+1; } ans_quotient.number[i-b.len+1]=w; head=number[i]; if(root==0&&w!=0) root=i-b.len+2; } ans_quotient.len=max(root,1); for(i=0; i<len; i++) ans_remainder.number[i]=number[i]; ans_remainder.len=1; for(i=len-1; i>=0; i--) { if(ans_remainder.number[i]) { ans_remainder.len=i+1; break; } } return ans_remainder; } bool operator==(biginteger &b) { if(len!=b.len) return false; int i; for(i=0; i<len; i++) { if(number[i]!=b.number[i]) return false; } return true; } bool operator!=(biginteger &b) { if(len!=b.len) return true; int i; for(i=0; i<len; i++) { if(number[i]!=b.number[i]) return true; } return false; } } c[105][105],dp[105][105],zero,one; void Print(biginteger a); biginteger Gcd(biginteger a,biginteger b) { while(b!=zero) { biginteger temp=b; b=a%b; a=temp; } return a; } void Print(biginteger a) { int i; printf("%lld",a.number[a.len-1]); for(i=a.len-2; i>=0; i--) printf("%09lld",a.number[i]); } int main() { one.len=1; one.number[0]=1; zero.len=1; int i,j,k; for(i=0; i<=100; i++) c[i][0]=c[i][i]=one; for(i=2; i<=100; i++) { for(j=1; j<i; j++) c[i][j]=c[i-1][j-1]+c[i-1][j]; } long long n,m,l; while(~scanf("%lld%lld%lld",&m,&n,&l)) { if(l>m) { printf("mukyu~\n"); continue; } for(i=0; i<=100; i++) { for(j=0; j<=100; j++) dp[i][j]=zero; } dp[0][0]=one; biginteger ans=zero; for(i=1; i<=n; i++) { for(j=1; j<=m; j++) { for(k=0; k<=j&&k<l; k++) { biginteger temp=dp[i-1][j-k]*c[m-(j-k)][k]; dp[i][j]=dp[i][j]+temp; } } ans=ans+dp[i][m]; } biginteger sum=one; for(i=0; i<m; i++) { biginteger x=zero; x.number[0]=n; sum=sum*x; } ans=sum-ans; biginteger gcd=Gcd(sum,ans); Print(ans/gcd); printf("/"); Print(sum/gcd); printf("\n"); } return 0; }