这题太妙了,所以来写题解;
注意到题目中的两个重要条件,(n imes tleq S,m-nleq 10^3);于是(sum_{i=1}^n x_i)一定不会超过(S);设这个和为(N),对于一个给定的(N),根据插板我们之后后面的方案数是(inom{S-N}{m-n})。
众所周知,(inom{x}{y})是一个关于(x)的(y)次多项式,所以(inom{S-N}{m-n})一定可以写成(sum_{i=0}^{m-n}f_i(S-N)^i)的形式,((S-N)^i)可以根据二项式定理来展开,于是我们如果能对于(kin [0,m-n])求出每一种方案的(N^k)之和,即(sum_{1leq x_ileq t,ileq n}(x_1+x_2+dots +x_n)^k)就能快速计算答案了。
显然可以倍增,用二项式定理合并答案,复杂度是(O((m-n)^2log n));其实也可以搞一个生成函数(F(x)=sum_{i=0}^{m-n}frac{sum_{j=1}^t j^i}{i!}x^i),求(F^n(x))即可,可以多项式exp,做到(O((m-n)^2)),但是由于我不会写暴力exp于是还是口胡一下就算了吧;
代码,只能在dark上过
#include<bits/stdc++.h>
#define re register
#define LL long long
const int mod=1e9+7,maxn=1e3+5;
inline int dqm(int x) {return x<0?x+mod:x;}
inline int qm(int x) {return x>=mod?x-mod:x;}
inline void upd(int &x,int y) {x+=y;if(x>=mod)x-=mod;}
inline int ksm(int a,int b) {
int S=1;for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)S=1ll*S*a%mod;return S;
}
LL Sum,lm;int n,m,ln,pre[maxn],pw[maxn],c[maxn][maxn];
int A[maxn],h[maxn],g[maxn],fac[maxn],ifac[maxn],__pw[maxn][maxn];
inline void Lagrange() {
if(!ln){h[0]=1;return;}h[1]=1;
for(re int i=1;i<ln;i++)
for(re int j=i;j>=0;j--) {
upd(h[j+1],h[j]);
h[j]=1ll*h[j]*(mod-i)%mod;
}
for(re int i=0;i<=ln;i++) h[i]=1ll*h[i]*ifac[ln]%mod;
}
inline int calc(int n,int k) {
for(re int i=0;i<=k+1;i++) pre[i]=__pw[i][k];
for(re int i=1;i<=k+1;++i) upd(pre[i],pre[i-1]);
if(n<=k+1) return dqm(pre[n]-(k==0));
int prd=1,tot=0;
for(re int i=0;i<=k+1;++i) prd=1ll*prd*dqm(n-i)%mod;
for(re int i=0;i<=k+1;++i) {
int v=1ll*prd*ksm(dqm(n-i),mod-2)%mod*pre[i]%mod;
v=1ll*ifac[i]*v%mod*ifac[k+1-i]%mod;
if((k+1-i)&1) v=dqm(-v);upd(tot,v);
}
return dqm(tot-(k==0));
}
inline void mul(int *B,int *C) {
for(re int nw=0,i=ln;i>=0;B[i]=nw,--i,nw=0)
for(re int j=0;j<=i;++j)
upd(nw,1ll*B[i-j]*C[j]%mod*c[i][j]%mod);
}
void solve(int n,int *f) {
if(n==1) {
for(re int i=0;i<=ln;++i) g[i]=f[i]=calc(lm%mod,i);
return;
}
solve(n>>1,f);mul(f,f);if(n&1)mul(f,g);
}
int main() {
scanf("%lld%lld%d%d",&Sum,&lm,&n,&m);
ln=m-n+1;fac[0]=ifac[0]=1;
for(re int i=1;i<=ln;++i)fac[i]=1ll*fac[i-1]*i%mod;
ifac[ln]=ksm(fac[ln],mod-2);
for(re int i=ln-1;i;i--)ifac[i]=1ll*ifac[i+1]*(i+1)%mod;
for(re int i=0;i<=ln;i++)__pw[i][0]=1,c[i][0]=c[i][i]=1;
for(re int i=1;i<=ln;i++)
for(re int j=1;j<=ln;++j) __pw[i][j]=1ll*__pw[i][j-1]*i%mod;
for(re int i=1;i<=ln;i++)
for(re int j=1;j<i;++j) c[i][j]=qm(c[i-1][j]+c[i-1][j-1]);
ln--;Lagrange();solve(n,A);int ans=0;Sum%=mod;
pw[0]=1;for(re int i=1;i<=ln;i++)pw[i]=1ll*pw[i-1]*Sum%mod;
for(re int i=0;i<=ln;++i) {
int nw=0;
for(re int j=0;j<=i;++j)
upd(nw,1ll*pw[i-j]*A[j]%mod*c[i][j]%mod*(j&1?mod-1:1)%mod);
upd(ans,1ll*h[i]*nw%mod);
}
printf("%d
",ans);
return 0;
}