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();
}
posted @ 2020-01-28 22:25  Shiina_Mashiro  阅读(147)  评论(0编辑  收藏  举报