Luogu P4593 [TJOI2018]教科书般的亵渎
Link
显然总共要\(m+1\)个亵渎。
记\(S(n)=\sum\limits_{i=1}^ni^{m+1}\),且认为\(a_{m+1}=n+1\),那么答案就是\(\sum\limits_{j=0}^m\sum\limits_{i=j+1}^{m+1}S(a_i-a_j-1)-S(a_{i-1}-a_j)\)。
转换一下之后就是\(\sum\limits_{j=0}^m(S(n-a_j)-\sum\limits_{i=j+1}^m(a_i-a_j)^{m+1})\)。
\(S(n)\)有Lagrange插值、Bernoulli数、Stirling数、递推、差分等求法。
#include<cstdio>
#include<algorithm>
const int N=57,P=1000000007;
int a[N],f[N],fac[N];
int read(){int x;scanf("%d",&x);return x;}
int mod(int x){return x+(x>>31&P);}
int inc(int a,int b){return mod(a+b-P);}
int dec(int a,int b){return mod(a-b);}
int mul(int a,int b){return 1ll*a*b%P;}
int pow(int a,int k){int r=1;for(;k;k>>=1,a=mul(a,a))if(k&1)r=mul(a,r);return r;}
int cal(int n,int k)
{
int sum=0,t=1;
if(n<=k) return f[n];
for(int i=1;i<=k;++i) t=mul(t,n-i);
for(int i=1;i<=k;i++) sum=((k-i)&1?dec:inc)(sum,mul(pow(mul(mul(n-i,fac[i-1]),fac[k-i]),P-2),f[i]));
return mul(sum,t);
}
void solve()
{
int n=read(),m=read(),ans=0;
for(int i=1;i<=m+3;++i) f[i]=inc(f[i-1],pow(i,m+1));
for(int i=1;i<=m;++i) a[i]=read();
std::sort(a+1,a+m+1);
for(int i=0;i<=m;++i)
{
ans=inc(ans,cal(n-a[i],m+3));
for(int j=i+1;j<=m;++j) ans=dec(ans,pow(a[j]-a[i],m+1));
}
printf("%d\n",ans);
}
int main()
{
fac[0]=1;
for(int i=1;i<=55;++i) fac[i]=mul(i,fac[i-1]);
for(int T=read();T;--T) solve();
}