bzoj 3028 食物——生成函数
Posted narh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 3028 食物——生成函数相关的知识,希望对你有一定的参考价值。
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3028
把式子写出来,化一化,变成 x / ((1-x)^4) ,变成几个 sigma 相乘的样子,用组合意义看一下第 n 项的系数,就是 n-1 的可以不选的划分,即 C( n-1+3,3 ) 。为了高精度方便,化成 (n+2)*(n+1)*n/6 。
别忘了取模。
注意读入高精度数字的方法。错了几次之后只会一位一位地读了……
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=1600,base=1e2,mod=10007; int a[N],b[N],c[N]; void rdn() { char ch=getchar(); while(ch>‘9‘||ch<‘0‘)ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘) b[++b[0]]=ch-‘0‘,ch=getchar(); for(int i=b[0];i>1;i-=2) a[++a[0]]=(b[i-1]<<3)+(b[i-1]<<1)+b[i]; if(b[0]&1)a[++a[0]]=b[1]; for(int i=a[0]+1;i<=b[0];i++)b[i]=0; } void print(int *a) { printf("%d",a[a[0]]); for(int i=a[0]-1;i;i--) printf("%02d",a[i]); puts(""); } void pls(int *b,int x) { b[1]+=x; for(int i=1;i<=b[0];i++) { if(b[i]<base)break; b[i+1]+=b[i]/base;b[i]%=base; } while(b[b[0]+1]) { b[0]++; b[b[0]+1]+=b[b[0]]/base;b[b[0]]%=base; } } void mul() { c[0]=a[0]+b[0]-1; for(int i=1;i<=a[0];i++) for(int j=1;j<=b[0];j++) c[i+j-1]+=a[i]*b[j]; for(int i=1;i<=c[0];i++) c[i+1]+=c[i]/base,c[i]%=base; while(c[c[0]+1]) { c[0]++; c[c[0]+1]+=c[c[0]]/base;c[c[0]]%=base; } for(int i=1;i<=c[0];i++) a[i]=c[i],c[i]=0; a[0]=c[0]; c[0]=0; } void div(int *a,int x) { for(int i=a[0];i;i--) { if(i>1) a[i-1]+=(a[i]%x)*base; a[i]/=x; } while(a[0]>1&&!a[a[0]])a[0]--; } void upd(int *a) { for(int i=a[0];i>1;i--) a[i-1]+=a[i]%mod*base; } int main() { rdn(); for(int i=0;i<=a[0];i++)b[i]=a[i]; pls(b,1);mul(); pls(b,1);mul(); div(a,6);upd(a); printf("%d ",a[1]%mod); return 0; }
以上是关于bzoj 3028 食物——生成函数的主要内容,如果未能解决你的问题,请参考以下文章