BZOJ3028食物——生成函数+泰勒展开

题目描述

明明这次又要出去旅游了,和上次不同的是,他这次要去宇宙探险!我们暂且不讨论他有多么NC,他又幻想了他应 该带一些什么东西。理所当然的,你当然要帮他计算携带N件物品的方案数。他这次又准备带一些受欢迎的食物, 如:蜜桃多啦,鸡块啦,承德汉堡等等当然,他又有一些稀奇古怪的限制:每种食物的限制如下: 承德汉堡:偶数个 可乐:0个或1个 鸡腿:0个,1个或2个 蜜桃多:奇数个 鸡块:4的倍数个 包子:0个,1个,2个或3个 土豆片炒肉:不超过一个。 面包:3的倍数个 注意,这里我们懒得考虑明明对于带的食物该怎么搭配着吃,也认为每种食物都是以‘个’为单位(反正是幻想嘛 ),只要总数加起来是N就算一种方案。因此,对于给出的N,你需要计算出方案数,并对10007取模。

输入

输入一个数字N,1<=n<=10^500

输出

如题 

样例输入

输入样例1
1
输入样例2
5

样例输出

输出样例1
1
输出样例2
35   对于每种食物的限制,我们可以用多项式形式来表示,$a_{i}x^i$表示这种食物取$i$个时的方案数是$a_{i}$。 那么对于每种食物,我们可以列出对应多项式,答案就是将所有多项式相乘后$x^n$的系数。 承德汉堡:$\sum\limits_{i=0}^{+\infty}x^{2i}=\frac{1}{1-x^2}$ 可乐:$1+x$ 鸡腿:$1+x+x^2=\frac{x^3-1}{x-1}$ 蜜桃多:$\sum\limits_{i=0}^{+\infty}x^{2i+1}=\frac{x}{1-x^2}$ 鸡块:$\sum\limits_{i=0}^{+\infty}x^{4i}=\frac{1}{1-x^4}$ 包子:$1+x+x^2+x^3=\frac{x^4-1}{x-1}$ 土豆片炒肉:$1+x$ 面包:$\sum\limits_{i=0}^{+\infty}x^{3i}=\frac{1}{1-x^3}$ 由等比数列求和公式即可推等式右边的部分,那么将所有生成函数都乘起来就能得到:$\frac{x}{(1-x)^4}$ 根据泰勒展开可以知道$\frac{1}{(1-x)^m}=(1+x+x^2+x^3+……)^m$,求第$n$项系数就是$C_{m-1}^{m+n-1}$ 乘上$x$就相当于把系数都右移一位,即求第$n-1$项系数为$C_{m-1}^{m+n-2}$,将$m=4$代入,那么答案就是$C_{3}^{n+2}$。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define mod 10007
using namespace std;
int ans;
int n;
char s[1000];
ll quick(int x,int y)
{
	ll res=1ll;
	while(y)
	{
		if(y&1)
		{
			res=res*x%mod;
		}
		y>>=1;
		x=1ll*x*x%mod;
	}
	return res;
}
int main()
{
	scanf("%s",s+1);
	int len=strlen(s+1);
	for(int i=1;i<=len;i++)
	{
		n=n*10+s[i]-'0';
		n%=mod;
	}
	ans=n*(n+1)%mod;
	ans=ans*(n+2)%mod;
	ans=ans*quick(6,mod-2)%mod;
	ans=(ans%mod+mod)%mod;
	printf("%d",ans);
}
上一篇:04 序列的运算


下一篇:windows客户端和linux虚拟机服务器实现简单socket通信