这个就是拉格朗日插值简化的公式
f(n)=∑i=0k+1(−1)k−i+1f(i)∏i−1j=0(n−j)∏k+1j=i+1(n−j)i!(k+1−i)!
f
(
n
)
=
∑
i
=
0
k
+
1
(
−
1
)
k
−
i
+
1
f
(
i
)
∏
j
=
0
i
−
1
(
n
−
j
)
∏
j
=
i
+
1
k
+
1
(
n
−
j
)
i
!
(
k
+
1
−
i
)
!
const ll mod=1e9+7;
const int maxn=1e3+10;
ll pref[maxn],pre_inv[maxn],f[maxn];
ll add(ll a,ll b){
if ((a+=b)>=mod) {
return a%mod;
}else return a;
}
ll sub(ll a,ll b){
if ((a-=b)<0) {
return (a+mod)%mod;
}else return a;
}
ll mul(ll a,ll b){
if((a*=b)>=mod)
return a%mod;
else return a;
}
ll qmod(ll a,ll b){
ll ans=1;
while (b) {
if (b&1) {
ans=mul(ans, a);
}
b/=2;
a=mul(a, a);
}
return ans;
}
void init(int k){
pref[0]=pre_inv[0]=1;
for (int i=1; i<=k+1; ++i) {
pref[i]=mul(pref[i-1],i);
}
pre_inv[k+1]=qmod(pref[k+1], mod-2);
for (int i=k; i>=1; --i) {
pre_inv[i]=mul(pre_inv[i+1],(i+1));
}
}
ll Lgr_polysum(int n,int k){
f[0]=0;
for (int i=1; i<=k+1; ++i) {
f[i]=add(f[i-1], qmod(i, k));
}
ll hpre[maxn],tpre[maxn];
hpre[0]=n;
for (int i=1;i<=k+1 ; ++i) {
hpre[i]=mul(hpre[i-1], n-i);
}
tpre[k+1]=sub(n,(k+1));
for (int i=k; i>=0; --i) {
tpre[i]=mul(tpre[i+1], sub(n,i));
}
ll ans=0;ll tmp;
for (int i=0; i<=k+1; ++i) {
if ((k+1-i)&1) {
tmp=mul(f[i], mul(pre_inv[i],pre_inv[k+1-i]));
if (i!=k+1)
tmp=mul(tmp, tpre[i+1]);
if(i)
tmp=mul(hpre[i-1], tmp);
ans=sub(ans, tmp);
}else{
tmp=mul(f[i],mul(pre_inv[i],pre_inv[k+1-i] ) );
if (i!=k+1) {
tmp=mul(tmp, tpre[i+1]);
}
if(i)
tmp=mul(hpre[i-1], tmp);
ans=add(ans, tmp);
}
}
return ans;
}