题意:
将正整数(n) 分解为(m) 个正整数相加(注意是有序的)。定义一种拆分的价值为拆分出的所有正整数的最大值。求所有拆分方案的价值之和。
题解:
我们考虑每个(k) 作为最大值,容斥一下,可以得到答案为
[sum_{k=1}^nk[x^n]((xfrac{1-x^k}{1-x})^m-(xfrac{1-x^{k-1}}{1-x})^m)
]
方便起见,我们令(f_k(x)=(xdfrac{1-x^k}{1-x})^m) ,那么原式变为
[sum_{k=1}^nk[x^n](f_k(x)-f_{k-1}(x))\
=[x^n](nf_n(x)-sum_{i=1}^{n-1}f_i(x))
]
现在我们考虑(f_k(x)) 的(x^n) 项的系数,有
[egin{aligned}
[x^n]f_k(x)\
&=[x^n]frac{x^m(1-x^k)^m}{(1-x)^m}\
&=[x^{n-m}](sum_tinom mt(-1)^tx^{kt})(sum_tinom{t+m-1}{m-1}x^t)\
&=sum_{i=0}^{n-m}[kmid i](-1)^{frac ik}inom m{frac ik}inom{n-i-1}{m-1}\
&=sum_{i=0}^{lfloorfrac{n-m}k
floor}(-1)^iinom miinom{n-ki-1}{m-1}
end{aligned}
]
注意到这是调和级数的形式,因此总复杂度为(mathcal O(nln n)) 。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5,mod=1e9+7;
int n,m,fac[N],fiv[N];
inline int qpow(int x,int y)
{
int ans=1;
for(;y;y>>=1,x=1ll*x*x%mod)
if(y&1)ans=1ll*ans*x%mod;
return ans;
}
inline void pre()
{
fac[0]=1;for(int i=1;i<=n;++i)fac[i]=1ll*fac[i-1]*i%mod;
fiv[n]=qpow(fac[n],mod-2);
for(int i=n-1;~i;--i)fiv[i]=1ll*fiv[i+1]*(i+1)%mod;
}
int main()
{
scanf("%d%d",&n,&m);pre();
ll ans=1ll*n*fac[n-1]%mod*fiv[n-m]%mod*fiv[m-1]%mod;
for(int k=1;k<n;++k)
{
int up=min(m,(n-m)/k);
for(int i=0,t=n-1;i<=up;++i,t-=k)
{
int tmp=1ll*m*fiv[i]%mod*fiv[m-i]%mod*fac[t]%mod*fiv[t-m+1]%mod;
(i&1)?ans+=tmp:ans-=tmp;
}
ans%=mod;if(ans<0)ans+=mod;
}
printf("%lld
",ans);
return 0;
}