大致题意: 给定你若干物品的数量要求(题解里有,这里省略),求选出(n)个物品的方案数。
前言
无意中刷到这道生成函数基础题。(生成函数可见这篇博客:初学生成函数(一)——普通生成函数)
上次【洛谷2000】拯救世界因为要高精结果没写坑掉了,这次一看不用高精就来水一发。
生成函数
考虑搞出每种物品的生成函数。
承德汉堡(偶数个):(x^0+x^2+x^4+...=frac1{1-x^2})
可乐((0)个或(1)个):(x^0+x^1=frac {1-x^2}{1-x})
鸡腿((0)个,(1)个或(2)个):(x^0+x^1+x^2=frac{1-x^3}{1-x})
蜜桃多(奇数个):(x^1+x^3+x^5+...=frac x{1-x^2})
鸡块((4)的倍数个):(x^0+x^4+x^8+...=frac1{1-x^4})
包子((0)个,(1)个,(2)个或(3)个):(x^0+x^1+x^2+x^3=frac{1-x^4}{1-x})
土豆片炒肉(不超过一个):(x^0+x^1=frac{1-x^2}{1-x})
面包((3)的倍数个):(x^0+x^3+x^6+...=frac1{1-x^3})
然后把这些东西全部乘在一起并约分(这一过程省略,相信大家都会)得到:
处理询问
询问问的是选出(n)个物品的方案数,也就是生成函数(n)次项的系数。
考虑该生成函数就等于(x(frac1{1-x})^4)。
由于(frac1{1-x}=sum_{i=0}^{infty}x^i),所以如果我们去掉(x)这一项,那就相当于求((sum_{i=0}^{infty}x^i)^4)第(n-1)项的次数。
也就是把(n-1)个格子划分为(4)部分(每一部分可以为空)的方案数,那么用隔板法,一共有(n)个间隔和(3)个板,方案数就是:
对于读入我们直接读入字符串,然后转化为(int)时同时取模,这样就可以避免高精了。
代码
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define LEN 500
#define X 10007
using namespace std;
int n;char s[LEN+5];
int main()
{
RI i,l;for(scanf("%s",s+1),i=1,l=strlen(s+1);i<=l;++i) n=((n<<3)+(n<<1)+(s[i]&15))%X;//转化过程中同时取模
return printf("%d",(1LL*(n+2)*(n+1)*n/6)%X),0;//输出C(n+2,3)
}