下面是BC官方题解:这题的本质是求
x1+x2+x3+……+xm=n
且
x1>x2,x3,x4,……,xm
这个方程有多少整数解。
可以枚举
x1
.设当前
x1=u
,那么问题转化为求
x1+x2+x3+……+xm=n−u
且
u>x2,x3,x4,……,xm
,可以用生成函数来解决。
每一个项的生成函数是
f(x)=1+x+x2+……+xu−1=1−xu1−x
那么
m−1
个相加的生成函数是
G(x)=[f(x)]m−1=(1−xu)m−1(1−x)m−1
再利用
(1+x)k=1+∑n=1∞k∗(k−1)∗(k−2)∗……∗(k−n+1)n!xn
对上边的分子分母进行展开。枚举分子中
xu
的次数,求出G(x)里
xn−u
的系数。总的复杂度是nlogn
不过题解讲的不是很清楚,对于1/(1-x)可以生成1+x+x^2+x^3...然后1/(1-x)^m也可以同样拆,对于分母就是一个多项式,直接枚举分母的次幂就行。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int mod=1000000007;
const int maxn=100005;
typedef long long LL;
LL jie[maxn<<1],fan[maxn<<1];
LL mm(int n,int m){
LL s=1;
LL k=n;
while(m>0){
if(m&1){
s=s*k;
s%=mod;
}
k=k*k;
k%=mod;
m>>=1;
}
return s;
}
void init(void){
int i;
jie[0]=1;
fan[0]=1;
for(i=1;i<=200000;i++){
jie[i]=jie[i-1]*i;
jie[i]%=mod;
fan[i]=mm(jie[i],mod-2);
}
}
LL zuhe(int n,int m){
LL s;
s=jie[n]*fan[m];
s%=mod;
s=s*fan[n-m];
s%=mod;
return s;
}
void solve(int n,int m){
int i,j;
LL s=1;
if(m==1){
cout<<"1"<<endl;
return ;
}
int p;
for(i=1;i<n;i++){
p=1;
for(j=0;j*i<=n-i&&j<=m-1;j++){
LL s1=0;
if(j<=m-1){
s1=zuhe(m-1,j)*zuhe(n-i-(j*i)+m-2,m-2)*p;
s1%=mod;
}
s+=s1;
s%=mod;
p=p*-1;
}
}
cout<<s<<endl;
}
int main()
{
init();
int n,m,t;
cin>>t;
while(t--){
cin>>n>>m;
solve(n,m);
}
}