bzoj 3028 食物 —— 生成函数
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3028
式子很好推,详细可以看这篇博客:https://blog.csdn.net/wu_tongtong/article/details/78856565
所以就是要求 C(n+2,3) ,n 很大但是模数很小,可以用 Lucas 定理;
总觉得真的写了高精度和 Lucas 定理有点麻烦...而且还因为一处忘记取模 RE 了一次...
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; int const xn=505,mod=10007; int jc[mod+5],jcn[mod+5]; char ch[xn]; struct N{int a[xn];}n; ll pw(ll a,int b) { ll ret=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1)ret=(ret*a)%mod; return ret; } int md(N x) { for(int i=x.a[0];i>1;i--) x.a[i-1]+=(x.a[i]%mod)*10,x.a[i]=0; return x.a[1]%mod;//%mod } int C(int n,int m){return ((ll)jc[n]*jcn[m])%mod*jcn[n-m]%mod;} int Lucas(N n,int m) { if(n.a[0]<=1&&n.a[1]<2)return 0; int p=md(n); return C(p,m%mod)%mod; } int main() { scanf("%s",ch+1); int l=n.a[0]=strlen(ch+1); for(int i=1;i<=l;i++)n.a[i]=ch[l-i+1]-'0'; n.a[1]+=2; for(int i=1;i<=l;i++)n.a[i+1]+=n.a[i]/10,n.a[i]%=10; if(n.a[l+1])n.a[0]++; jc[0]=1; for(int i=1;i<mod;i++)jc[i]=(ll)jc[i-1]*i%mod; jcn[mod-1]=pw(jc[mod-1],mod-2); for(int i=mod-2;i>=0;i--)jcn[i]=(ll)jcn[i+1]*(i+1)%mod; printf("%d\n",Lucas(n,3)); return 0; }