BZOJ3028 食物 (生成函数)

时间:2021-11-08 12:37:15

首先 1+x+x^2+x^3+...+x^∞=1/(1-x)

对于题目中的几种食物写出生成函数 (对于a*x^b , a表示方案数 x表示食物,b表示该种食物的个数)

f(1)=1+x^2+x^4+...+x^∞=1/(1-x^2)

f(2)=1+x

f(3)=1+x+x^2

f(4)=x+x^3+x^5+...+x^∞=x/(1-x^2)

f(5)=1+x^4+x^8+...+x^∞=1/(1-x^4)

f(6)=1+x+x^2+x^3

f(7)=1+x

f(8)=1+x^3+x^6+...+x^∞=1/(1-x^3)

把这些母函数相乘得到最后各种食物个数的方案数。

g(x)=x(1+x)^2(1+x+x^2)(1+x+x^2+x^3)/(1-x^2)^2(1-x^3)(1-x^4)

因为 1+x+x^2=(1-x^3)/(1-x) , 1+x+x^2+x^3=(1-x^4)/(1-x)

可以得到g(x)=x/(1-x)^4

对于(1-x)^-k的展开式为sigma(C(-k,n)*(-x)^n)

C(-k,n) = (-k)*(-k-1)*...*(-k-n+1)/n! = (-1)^n*(n+k-1)*(n+k-2)*...*k/n!=(-1)^n*C(n+k-1,n)

那么 C(-k,n)*(-x)^n = C(n+k-1,n)*x^n

所以 g(x)的第n项系数为 x*C(n-1+4-1,n-1)*x^n-1 即 C(n+2,3)

对于所给的n取模,再求6关于10007的逆元即可

 var s:ansistring;
n,i:longint;
function pow(x,y:longint):longint;
var sum:longint;
begin
sum:=;
while y> do
begin
if y mod = then sum:=sum*x mod ;
x:=x*x mod ;
y:=y div ;
end;
exit(sum);
end;
begin
readln(s);
n:=;
for i:= to length(s) do
n:=(n*+ord(s[i])-) mod ;
writeln(n*(n+)*(n+)*pow(,) mod );
end.