BZOJ3028 食物

来源:互联网 发布:windows不显示桌面 编辑:程序博客网 时间:2024/03/29 22:23

跟xuruifan小犇学习了生成函数,感觉好神啊

对于一个数列a1,a2,a3,a4....,其生成函数就是a1+a2*x+a3*x^2+a4*x^3.....

对于一种物品,造一个序列,如果这种物品可以选x个,那么第x项就是1,否则就是0,对这个序列求生成函数

把所有生成函数相乘,次数为n的项的系数就是选一共n个物品的方案数,因为多项式相乘之后如果两个生成函数里两项次数分别为x,y,那么结果里次数为x+y的项的系数就会加上这两项的系数的积(事实上我们可以由此显然看出多项式乘法是一个卷积形式,之前写高精乘来理解的我是多么的naive)

对于这道题,因为n过大,所以直接乘是不行的

把所有物品的生成函数求出来,手动相乘然后化简

可以选x的倍数个的生成函数相当于对一个无限等比数列求和,因为生成函数的x可以取任意值,不妨取(0,1)之间的数,这样x的无限次方就得0

化简得到x/((1-x)^4)

x的意义是必须选一个,1/(1-x)的意义是可以选任意个

那么答案就相当于有5种物品,其中1种必须选一个,剩下4种可以任意选

也就是C(n+2,3)

上高精即可

#include<iostream>#include<cstdlib>#include<cstdio>#include<cstring>#include<ctime>#include<cmath>#include<algorithm>#include<iomanip>#include<queue>#include<map>#include<bitset>#include<stack>#include<vector>#include<set>using namespace std;#define MAXN 10010#define MAXM 10010#define INF 1000000000#define MOD 1000000007#define ll long long#define eps 1e-8#define MAXL 10010char bnin[MAXL];struct bn{char x[MAXL];int n;bn(){memset(x,0,sizeof(x));n=0;}bn(int X){memset(x,0,sizeof(x));n=0;while(X){x[++n]=X%10;X/=10;}}friend istream &operator >>(istream &input,bn &x){int i;input>>bnin;memset(x.x,0,sizeof(x.x));x.n=strlen(bnin);for(i=1;i<=x.n;i++){x.x[i]=bnin[x.n-i]-'0';}return input;}friend ostream &operator <<(ostream &output,bn x){int i;if(!x.n){output<<0;}for(i=x.n;i;i--){output<<int(x.x[i]);}return output;}void rd(){int i;scanf("%s",bnin);n=strlen(bnin);for(i=1;i<=n;i++){x[i]=bnin[n-i]-'0';}}void pt(){int i;if(!n){printf("0");}for(i=n;i;i--){printf("%d",x[i]);}}void half(){int i;for(i=n;i;i--){x[i-1]+=(x[i]%2)*10;x[i]/=2;}x[0]=0;while(!x[n]&&n){n--;}}bn operator =(ll y){for(this->n=1;y!=0;this->x[this->n]=y%10,y/=10,this->n++){}this->n--;return *this;}friend bool operator <(bn x,bn y){int i;if(x.n!=y.n){return x.n<y.n;}for(i=x.n;i;i--){if(x.x[i]!=y.x[i]){return x.x[i]<y.x[i];}}return 0;}friend bool operator ==(bn x,bn y){int i;if(x.n!=y.n){return 0;}for(i=x.n;i;i--){if(x.x[i]!=y.x[i]){return 0;}}return 1;}friend bool operator >(bn x,bn y){return !(x<y||x==y);}friend bool operator <=(bn x,bn y){return x<y||x==y;}friend bool operator >=(bn x,bn y){return x>y||x==y;}friend bool operator <(bn x,ll y){return x<bn(y);}friend bool operator ==(bn x,ll y){return x==bn(y);}friend bool operator >(bn x,ll y){return x==bn(y);}friend bool operator <=(bn x,ll y){return x==bn(y);}friend bool operator >=(bn x,ll y){return x==bn(y);}friend bool operator <(ll x,bn y){return bn(x)<y;}friend bool operator ==(ll x,bn y){return bn(x)==y;}friend bool operator >(ll x,bn y){return bn(x)==y;}friend bool operator <=(ll x,bn y){return bn(x)==y;}friend bool operator >=(ll x,bn y){return bn(x)==y;}friend bn operator +(bn x,bn y){bn z;int i;for(i=1;i<=x.n||i<=y.n;i++){z.x[i]+=x.x[i]+y.x[i];z.x[i+1]+=z.x[i]/10;z.x[i]%=10;}z.n=max(x.n,y.n);if(z.x[z.n+1]){z.n++;}return z;}friend bn operator -(bn x,bn y){bn z;int i;for(i=1;i<=x.n||i<=y.n;i++){z.x[i]+=x.x[i]-y.x[i];if(z.x[i]<0){z.x[i+1]--;z.x[i]+=10;}}z.n=max(x.n,y.n);while(!z.x[z.n]&&z.n){z.n--;}return z;}friend bn operator *(bn x,bn y){bn z;int i,j;for(i=1;i<=x.n;i++){for(j=1;j<=y.n;j++){z.x[i+j-1]+=x.x[i]*y.x[j];z.x[i+j]+=z.x[i+j-1]/10;z.x[i+j-1]%=10;}}z.n=x.n+y.n;while(!z.x[z.n]&&z.n){z.n--;}return z;}friend bn operator +(bn x,ll y){return x+bn(y);}friend bn operator -(bn x,ll y){return x-bn(y);}friend bn operator *(bn x,ll y){return x*bn(y);}friend bn operator +(ll x,bn y){return bn(x)+y;}friend bn operator -(ll x,bn y){return bn(x)-y;}friend bn operator *(ll x,bn y){return bn(x)*y;}friend bn operator /(bn x,bn y){bn z;bn l,r,mid;l=0;r=x;while(l<=r){mid=l+r;mid.half();if(mid*y<=x){z=mid;l=mid+1;}else{r=mid-1;}}return z;}friend bn operator /(bn x,ll y){return x/bn(y);}friend bn operator /(ll x,bn y){return bn(x)/y;}friend bn operator %(bn x,bn y){return x-(y*(x/y));}bn operator +=(bn x){(*this)=(*this)+x;return (*this);}bn operator -=(bn x){(*this)=(*this)-x;return (*this);}bn operator *=(bn x){(*this)=(*this)*x;return (*this);}bn operator /=(bn x){(*this)=(*this)/x;return (*this);}bn operator %=(bn x){(*this)=(*this)%x;return (*this);}bn operator +=(ll x){(*this)=(*this)+x;return (*this);}bn operator -=(ll x){(*this)=(*this)-x;return (*this);}bn operator *=(ll x){(*this)=(*this)*x;return (*this);}bn operator /=(ll x){(*this)=(*this)/x;return (*this);}bn operator %=(ll x){(*this)=(*this)%x;return (*this);}ll tonum(){ll re=0;int i;for(i=n;i;i--){re*=10;re+=x[i];}return re;}friend bn sqrt(bn x){bn z;bn l,r,mid;l=0;r=x;while(l<=r){mid=l+r;mid.half();if(mid*mid<=x){z=mid;l=mid+1;}else{r=mid-1;}}return z;}};bn n;bn ans=1;int main(){cin>>n;ans=(n+2)*(n+1)*(n);ans=ans/6;cout<<ans%10007<<endl;return 0;}/**/


 

0 0
原创粉丝点击