题解 P4593 【[TJOI2018]教科书般的亵渎】
题目意思有些乱
但其实实际上我们可以转化成求
那么这就是个经典的求自然数幂和的问题了,有很多种方法解决,以下给出几种常见方法
1.递推法
令其为S(n,k),可得
相加可得
于是这样我们可以在
2.
但是我们也可以用
可得到
其中
3.
(1)下降幂:
(2)第一类斯特林数:
那么我们可得
所以有
$$= k! \binom{n + 1}{k + 1} - \sum_{j = 0}^{k - 1} \left[\begin{matrix} k \\ j \end{matrix}\right] (-1)^{k - j}{\sum_{i = 0}^{n} i^j}$$
$$= \frac{(n + 1)^{\underline{k + 1}}}{k + 1} - \sum_{j = 0}^{k - 1} \left[\begin{matrix} k \\ j \end{matrix}\right] (-1)^{k - j}{\sum_{i = 0}^{n}i^j}$$
4.多项式差分
考虑
我们有
$$= \sum_{j = 0}^{k} \sum_{i = 0}^{n} c_j \binom{i}{j}$$
$$= \sum_{j = 0}^{k} c_j \binom{n + 1}{j + 1}$$
如果模数为质数,就可以
5.拉格朗日插值
从上面方法可看出
我们把
于是可以做到
我用的是
代码如下:
// luogu-judger-enable-o2
#include <bits/stdc++.h>
#define F(i, l, r) for(int i = (l), _end_ = (int)(r); i <= _end_; ++i)
#define f(i, r, l) for(int i = (r), _end_ = (int)(l); i >= _end_; --i)
#define Set(a, v) memset(a, v, sizeof(a))
#define file(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
using namespace std;
bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;}
bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;}
inline long long read() {
long long x = 0, fh = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar() ) if (ch == '-') fh = -1;
for (; isdigit(ch); ch = getchar() ) x = (x<<1) + (x<<3) + (ch ^ '0');
return x * fh;
}
const int mod=1e9+7;
long long n,a[65];
int m;
int b[65],c[65][65],inv[65];
long long qpow(long long x,long long y){
long long res=1;
while(y){
if(y&1)res=res*x%mod;
x=x*x%mod;
y>>=1;
}
return res;
}
int fx(long long x){
int res=0;
F(i,1,m+1){
res=(res+1ll*c[m+1][i]*b[m+1-i]%mod*qpow(x+1,i)%mod)%mod;
}
res=1ll*res*qpow(m+1,mod-2)%mod;
return res;
}
int main () {
#ifndef ONLINE_JUDGE
file("4593");
#endif
int t=read();
F(i,1,60)inv[i]=qpow(i,mod-2);
F(i,0,60){
c[i][0]=1;
F(j,1,i){
c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
}
}
b[0]=1;
F(i,1,60){
b[i]=0;
F(j,0,i-1)b[i]=(b[i]+1ll*c[i+1][j]*b[j])%mod;
b[i]=(1ll*(mod-b[i])*inv[i+1])%mod;
}
while(t--){
n=read();
m=read();
F(i,1,m)a[i]=read();
a[++m]=++n;
sort(a+1,a+m+1);
long long ans=0;
F(i,1,m){
F(j,i,m){
ans=(ans+fx(a[j]-1)-fx(a[j-1])+mod)%mod;
}
F(j,i+1,m)a[j]-=a[i];
a[i]=0;
}
printf("%lld\n",ans);
}
return 0;
}