拉格朗日插值法--CF622F The Sum of the k-th Powers
阿新 • • 發佈:2018-11-24
傳送門
注意到把
作為
作為
這其實是一個
次多項式,把前
個點當成已知點,就可以拉格朗日插值法做了。
注意轉移的時候乘除就好了,可以預處理字首積和字尾積,把複雜度降下來。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define maxn 1000005
#define LL long long
using namespace std;
int n,m;
LL ans,mul1[maxn],mul2[maxn];
const int mod=1e9+7;
inline LL qpow(LL x,int k){
LL ret=1;
while(k){
if(k&1) (ret*=x)%=mod;
(x*=x)%=mod; k>>=1;
} return ret%mod;
}
int main(){
scanf("%d%d",&n,&m);
if(n==1) return puts("1"),0;
mul1[1]=n-1; mul2[m+2]=(n-m-2+mod)%mod; mul1[0]=mul2[m+3]=1;
for(int i=2;i<=m+2;i++) mul1[i]=mul1[i-1]*(n-i+mod)%mod;
for(int i=m+1;i>=1;i--) mul2[i]=mul2[i+1]*(n-i+mod)%mod;
LL yi=0,fm=1;
for(int i=2;i<=m+2;i++) fm=fm*(1-i+mod)%mod;
for(int i=1;i<=m+2;i++){
yi+=qpow(i,m)%mod; yi%=mod;
LL fz=mul1[i-1]*mul2[i+1]%mod;
if(i!=1) fm=fm*(i-1)%mod,fm=fm*qpow((i-m-3+mod)%mod,mod-2)%mod;
(ans+=yi*fz%mod*qpow(fm,mod-2)%mod)%=mod;
}
printf("%lld\n",ans);
return 0;
}