题意:每个数字的取值范围为0到n-1,共有m个数字,求总和为k的方案数。
因为k的上限为1e5,那么我们不妨把k看做k个1,然后通过m-1个隔板来分割出m个数字。但是这么做会有一个问题,那就是数字可能为0。那么不妨将数字的取值范围改成1-n,m个数所以k要相应的变成k+m,那么就可以使用隔板法了。
先无限制的求一下总数:C(m+k-1,m-1)
如果我们现在拿出来n个1,将剩下的数分割成m个数,那么把这n个1放到任何位置上,都是至少有一个数字超出限制的。
也就是:C(m+k-1,m-1)-C(m,1)*C(m+k-1-n,m-1)+C(m,2)*C(m+k-1-2n,m-1).... C(m,x)*C(m+k-1-xn,m-1) //奇 偶 判断加减
如此反复直到不合法结束,到x结束也就是 到无法满足至少x个数超过限制时结束。
比赛的时推了半天不知道为什么没有推导出来,很难受,只想到了O((k/n)^2)的算法,相当的难受啊
看了dls的讲解,顺便学习了一波推生成函数的方法
题意很简单,就是将k分成n个数,每个数的范围是[0,n-1],问一共有多少中方法
我们先不看k,只看n和m
当n=2时
0 1 2 3 4 5 6 7 8 9 10 11... 0 1 1 1 1 2 1 2 1 3 1 3 3 1 4 1 4 6 4 1 5 1 5 10 10 5 1 6 1 6 15 20 15 6 1 7 1 7 21 35 35 21 7 1 8 1 8 28 56 70 56 28 8 1 9 1 9 36 84 126 126 84 36 9 1 10 1 10 45 120 210 252 210 120 45 10 1 11 1 11 55 165 330 462 462 330 165 55 11 1 |
很显然就是杨辉三角,直接二项式定理就可以了
当n=3是,也是类似的
0 1 2 3 4 5 6 7 8 9 10 11 12
0: 1
1: 1 1 1
2: 1 2 3 2 1
3: 1 3 6 7 6 3 1
4: 1 4 10 16 19 16 10 4 1
5: 1 5 15 30 45 51 45 30 15 5 1
6: 1 6 21 50 90 126 141 126 90 50 21 6 1
生成公式:
这个公式就是就可以表示第m行的结果,对应的系数就是展开式中x^i的系数,所以我们只需要求生成公式中x^k的系数即可。
那么我们就得对公式化简
根据泰勒展开:
可得
所以
到了这一步,我们就可以直接计算了
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
#define LL long long
const LL N = 3e5 + 10;
const LL MAXN = 3e5;
const LL mod = 998244353;
LL fac[N];
LL inv[N];
LL qkm(LL base,LL b)
{
LL ans=1;
while(b!=0){
if(b&1!=0) ans=ans*base%mod;
base=base*base%mod;
b>>=1;
}
return ans;
}
LL C(LL n,LL m)
{
if(m>n) return 0;
return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int main()
{
fac[0]=fac[1]=1;
for(LL i=2;i<=MAXN;i++)
fac[i]=fac[i-1]*i%mod;
inv[MAXN]=qkm(fac[MAXN],mod-2);
for(LL i=MAXN-1;i>=0;i--)
inv[i]=inv[i+1]*(i+1)%mod;
/* for(int i=MAXN;i>=MAXN-10;i--)
cout<<inv[i]%mod<<" ";
cout<<endl;*/
LL T;
cin>>T;
while(T--){
LL n,m,k;
cin>>n>>m>>k;
LL ans=C(k+m-1,m-1);
LL p=1;
LL di = k+m-1-n;
LL num=1;
while(di>=m-1){
if(p){
ans=ans-C(m,num)*C(di,m-1)%mod+mod;
ans%=mod;
}else{
ans=ans+C(m,num)*C(di,m-1)%mod;
ans%=mod;
}
p=p^1;
num++;
di-=n;
}
cout<<ans<<endl;
}
return 0;
}
转载:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1001&cid=809
转载: https://blog.csdn.net/njupt_lyy/article/details/81714203
关于生成函数:http://www.matrix67.com/blog/archives/120