贴一点生成函数的前置知识
能直接求得指定指数的系数,生成函数就好做了。
食物
链接:https://www.acwing.com/problem/content/3135/
大意
给定一些食物携带个数的限制,求携带n件食物有多少种方案。
思路
生成函数板题,写出每种食物的生成函数,相乘抵消,求得指数为n时的系数。
函数如下
承德汉堡: 1 + x 2 + x 4 + . . . + x 2 k + . . . = 1 1 − x 2 1 + x^2 + x^4 + ... + x^{2k} + ... = \frac{1}{1-x^2} 1+x2+x4+...+x2k+...=1−x21
可乐: 1 + x = 1 − x 2 1 − x 1+x=\frac{1-x^2}{1-x} 1+x=1−x1−x2
鸡腿: 1 + x + x 2 = 1 − x 3 1 − x 1+x+x^2=\frac{1-x^3}{1-x} 1+x+x2=1−x1−x3
蜜桃多: x 1 + x 3 + . . . + x 2 k + 1 + . . . = x 1 − x 2 x^1 + x^3 + ... + x^{2k+1} + ... = \frac{x}{1-x^2} x1+x3+...+x2k+1+...=1−x2x
鸡块: 1 + x 4 + x 8 + . . . + x 4 k + . . . = 1 1 − x 4 1 + x^4 + x^8 + ... + x^{4k} + ... = \frac{1}{1-x^4} 1+x4+x8+...+x4k+...=1−x41
包子: 1 + x + x 2 + x 3 = 1 − x 4 1 − x 1+x+x^2+x^3=\frac{1-x^4}{1-x} 1+x+x2+x3=1−x1−x4
土豆片炒肉: 1 + x = 1 − x 2 1 − x 1+x=\frac{1-x^2}{1-x} 1+x=1−x1−x2
面包: 1 + x 3 + x 6 + . . . + x 3 k + . . . = 1 1 − x 3 1 + x^3 + x^6 + ... + x^{3k} + ... = \frac{1}{1-x^3} 1+x3+x6+...+x3k+...=1−x31
全部相乘后得到 x ( 1 − x ) 4 \frac{x}{(1-x)^4} (1−x)4x
这就可以用到上面的麦克劳林展开了,我们最终得到 ∑ k = 0 ∞ C k + 3 3 ∗ x k + 1 \sum_{k=0}^∞ C _{k+3}^3* x^{k+1} ∑k=0∞Ck+33∗xk+1
令k+1=n,得到k=n-1;
最终得到公式 C n + 2 3 C_{n+2}^3 Cn+23
CODE
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
ll n=0;
string s;
cin>>s;
for(int i=0;i<s.size();i++)
{
n=(n*10+s[i]-'0')%10007;
}
cout<<n*(n+1)*(n+2)/6%10007<<endl;
return 0;
}
Link with Balls——2021杭电中超第七场
链接:https://acm.hdu.edu.cn/showproblem.php?pid=7047
大意
有2*n个盒子,两种盒子每种n个:
第一种第i个盒子可以取ik个球(k∈N)
第二种第i个盒子可以取不超过i个球。
求取m个球有多少种方案。
思路
生成函数的思想,第一种第i个盒子的函数为 1 + x i + x 2 i + x 3 i + . . . + x k i + . . . = 1 1 − x i 1+x^i+ x^{2i}+ x^{3i}+... +x^{ki}+...=\frac{1}{1-x^i} 1+xi+x2i+x3i+...+xki+...=1−xi1
第一种第i个盒子的函数为 1 + x 1 + x 2 + x 3 + . . . + x i = 1 − x i + 1 1 − x 1+x^1+ x^{2}+ x^{3}+... +x^{i}=\frac{1-x ^{i+1}}{1-x} 1+x1+x2+x3+...+xi=1−x1−xi+1
2n个盒子函数相乘抵消得到 ( 1 − x n + 1 ) ∗ ( 1 1 − x ) n + 1 (1-x^{n+1})*(\frac{1}{1-x})^{n+1} (1−xn+1)∗(1−x1)n+1
麦克劳伦展开 ∑ k = 0 ∞ C i + n n ∗ x k − ∑ k = 0 ∞ C i + n n ∗ x k + n + 1 \sum_{k=0}^∞ C _{i+n}^n* x^{k}-\sum_{k=0}^∞ C _{i+n}^n* x^{k+n+1} ∑k=0∞Ci+nn∗xk−∑k=0∞Ci+nn∗xk+n+1
令左边k=m 右边k+n+1=m分别得到k=m 和 k=m-n-1
所以我们有最终公式
C m + n n − C m − 1 n C_{m+n}^n-C_{m-1}^n Cm+nn−Cm−1n
CODE
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e2+10;
const double eps=1e-6;
const ll mod = 1e9+7;
ll fac[2000007];
ll ksm(ll x,ll p){
ll res=1;
while(p){
if(p%2==1) res=res*x%mod;
p/=2;
x=x*x%mod;
}
return res;
}
ll inv(ll a) {
return ksm(a,mod-2)%mod;
}
void solve() {
fac[0] = 1;
for(int i = 1;i < 2000006; i++) {
fac[i] = (fac[i-1]*i)%mod;
}
}
ll comb(ll n,ll k){
if(k>n)return 0;
if(k==1)return n;
return (fac[n]*inv(fac[k])%mod*inv(fac[n-k])%mod);
}
int main()
{
ios::sync_with_stdio(0);
int t;
cin>>t;
solve();
while(t--)
{
int n,m;
cin>>n>>m;
cout<<(comb(m+n,n)-comb(m-1,n)+mod)%mod<<endl;
}
return 0;
}