1. 程式人生 > >[BZOJ 3028]食物(生成函數)

[BZOJ 3028]食物(生成函數)

cst net logs 成了 -s urn eight 土豆 art

Description

明明這次又要出去旅遊了,和上次不同的是,他這次要去宇宙探險! 我們暫且不討論他有多麽NC,他又幻想了他應該帶一些什麽東西。理所當然的,你當然要幫他計算攜帶N件物品的方案數。 他這次又準備帶一些受歡迎的食物,如:蜜桃多啦,雞塊啦,承德漢堡等等 當然,他又有一些稀奇古怪的限制: 每種食物的限制如下:   承德漢堡:偶數個   可樂:0個或1個   雞腿:0個,1個或2個   蜜桃多:奇數個   雞塊:4的倍數個   包子:0個,1個,2個或3個   土豆片炒肉:不超過一個。   面包:3的倍數個 註意,這裏我們懶得考慮明明對於帶的食物該怎麽搭配著吃,也認為每種食物都是以‘個’為單位(反正是幻想嘛),只要總數加起來是N就算一種方案。因此,對於給出的N,你需要計算出方案數,並對10007取模。 Solution
1<=n<=10^500 所以看起來就是要推柿子了 (母函數的一些相關姿勢可以看這裏) 把一堆生成函數的閉形式乘起來可以得到 x/(1-x)4 即 x*(1+x+x2+x3+x4...)4

技術分享

技術分享

但是“不定方程的非負整數解的個數”是我一點也不熟悉的問題= =

於是我找到了這個:-wzq

嗯!然後就得到了:這個柿子n次項的系數就是C(3,n+3),因為還乘了一個x所以我們把它平移一位變成了C(3,n+2)

所以說答案就是(n+2)(n+1)n/6

#include<iostream>
#include<cstdio>
#include
<cstring> #define Mod 10007 using namespace std; int read() { int x=0;char c=getchar(); while(c<0||c>9)c=getchar(); while(c>=0&&c<=9){x=(x*10+c-0)%Mod;c=getchar();} return x; } void exgcd(int a,int b,int &x,int &y,int &d) { if(!b){d=a,x=1
,y=0;return;} exgcd(b,a%b,y,x,d);y-=x*(a/b); } int inv(int a,int p) { int d,x,y;exgcd(a,p,x,y,d); return (x+p)%p; } int main() { int n=read(); printf("%d\n",((((n+2)*(n+1))%Mod*n)%Mod*inv(6,Mod))%Mod); return 0; }

[BZOJ 3028]食物(生成函數)