P1771 方程的解_NOI导刊2010提高(01)
按题意用快速幂把$g(x)$求出来
发现这不就是个组合数入门题吗!
$k$个人分$g(x)$个苹果,每人最少分$1$个,有几种方法?
根据插板法,显然答案为$C(g(x)-1,k-1)$
蓝后写个高精度。(我曾经十分天真地认为$ans<=10^{50}$)
这里用压位+结构体重载高精。可以应对$ans<=10^{24*7}$的数据。
注意:存在x,P,$(x^x) \% P!=(x\% P)^{(x\% P)} \% P$
#include<iostream> #include<cstdio> #include<cstring> #define re register using namespace std; int max(int a,int b){return a>b?a:b;} const int W=10000000;//压7位 int x,k; struct bigsum{ int a[25],len; bigsum(){memset(a,0,sizeof(a));len=0;} bigsum operator + (const bigsum &tmp) const{ bigsum c; int x=0; c.len=max(len,tmp.len); for(int i=1;i<=c.len;++i){ c.a[i]=a[i]+tmp.a[i]+x; x=c.a[i]/W;c.a[i]%=W; } for(;x;x/=W) c.a[++c.len]=x%W; return c; } void print(){//注意压位高精输出时每一位的前导0 printf("%d",a[len]); for(int i=len-1;i>=1;--i){ for(int j=10;a[i]*j<W;j*=10) putchar(48); printf("%d",a[i]); } } }C[1001][1001]; int Pow(int x,int y){ int res=1; for(;y;y>>=1,x=1ll*x*x%1000) if(y&1) res=1ll*res*x%1000; return res; } int main(){ scanf("%d%d",&k,&x); x=Pow(x%1000,x); if(!x){puts("0");return 0;} for(int i=0;i<x;++i) for(int j=0;j<=i;++j){ if(!j||j==i) C[i][j].a[C[i][j].len=1]=1; else C[i][j]=C[i-1][j]+C[i-1][j-1]; }//杨辉三角递推 C[x-1][k-1].print(); return 0; }