1. 程式人生 > >P1771 方程的解_NOI導刊2010提高(01)

P1771 方程的解_NOI導刊2010提高(01)

P1771 方程的解_NOI導刊2010提高(01)

按題意用快速冪把$g(x)$求出來

發現這不就是個組合數入門題嗎!

$k$個人分$g(x)$個蘋果,每人最少分$1$個,有幾種方法?

根據插板法,顯然答案為$C(g(x)-1,k-1)$

藍後寫個高精度。(我曾經十分天真地認為$ans<=10^{50}$)

這裡用壓位+結構體過載高精。可以應對$ans<=10^{24*7}$的資料。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define
re register 5 using namespace std; 6 int max(int a,int b){return a>b?a:b;} 7 const int W=10000000; 8 int x,k; 9 struct bigsum{ 10 int a[25],len; 11 bigsum(){memset(a,0,sizeof(a));len=0;} 12 bigsum operator + (const bigsum &tmp) const{ 13 bigsum c; int x=0; 14 c.len=max(len,tmp.len);
15 for(int i=1;i<=c.len;++i){ 16 c.a[i]=a[i]+tmp.a[i]+x; 17 x=c.a[i]/W;c.a[i]%=W; 18 } 19 for(;x;x/=W) c.a[++c.len]=x%W; 20 return c; 21 } 22 void print(){//注意壓位高精輸出時每一位的前導0 23 printf("%d",a[len]); 24 for(int i=len-1
;i>=1;--i){ 25 for(int j=10;a[i]*j<W;j*=10) putchar(48); 26 printf("%d",a[i]); 27 } 28 } 29 }C[1001][1001]; 30 int Pow(int x,int y){ 31 int res=1; 32 for(;y;y>>=1,x=1ll*x*x%1000) 33 if(y&1) res=1ll*res*x%1000; 34 return res; 35 } 36 int main(){ 37 scanf("%d%d",&k,&x); x%=1000;x=Pow(x,x); 38 for(int i=0;i<x;++i) 39 for(int j=0;j<=i;++j){ 40 if(!j||j==i) C[i][j].a[C[i][j].len=1]=1; 41 else C[i][j]=C[i-1][j]+C[i-1][j-1]; 42 }//楊輝三角遞推 43 C[x-1][k-1].print(); 44 return 0; 45 }
View Code