# 拉格朗日插值法(图文详解)

https://blog.csdn.net/xyz32768/article/details/81233900

1.想到是一个多项式

2.点值的取值是有讲究的，1~k+2这样连续的整点有助于预处理减少复杂度（跟自己干嘛要过不去23333）

# CF622F The Sum of the k-th Powers

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
char ch;x=0;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*10+numb);
(fl==true)&&(x=-x);
}
namespace Miracle{
const int N=1e6+5;
const int mod=1e9+7;
int n,k;
int qm(int x,int y){
int ret=1;
while(y){
if(y&1) ret=(ll)ret*x%mod;
x=(ll)x*x%mod;
y>>=1;
}
return ret;
}
ll pre[N],bac[N];
ll fu[N];
ll y[N];
ll sol(){
ll ret=0;
for(reg i=1;i<=k+2;++i){
//cout<<" i "<<i<<" : "<<y[i]<<" "<<pre[i-1]<<" "<<pre[k+2-i]<<" "<<bac[k+2]<<" "<<n-i<<endl;
if(n>k+2) ret=(ret+y[i]*qm(pre[i-1]*(fu[k+2-i])%mod,mod-2)%mod*(bac[k+2]*qm((n-i),mod-2)%mod)%mod)%mod;
else {
if(n!=i) ret=(ret+y[i]*qm(pre[i-1]*(fu[k+2-i])%mod,mod-2)%mod*(bac[k+2]*qm(((n-i)+mod)%mod,mod-2)%mod)%mod)%mod;
else ret=(ret+y[i])%mod;
}
//    cout<<" ret "<<ret<<endl;
}
return ret;
}
int main(){
rd(n);rd(k);
pre[0]=1;
bac[0]=1;
fu[0]=1;
y[0]=0;
for(reg i=1;i<=k+2;++i){
pre[i]=pre[i-1]*i%mod;
fu[i]=fu[i-1]*(mod-i)%mod;
bac[i]=(bac[i-1]*(n-i)%mod+mod)%mod;
y[i]=(y[i-1]+qm(i,k))%mod;
}
printf("%lld",sol());
return 0;
}

}
signed main(){
Miracle::main();
return 0;
}

/*
Author: *Miracle*
Date: 2019/1/16 15:31:40
*/
View Code

upda:2019.2.18

$f(i) \frac{\Pi_{j!=i}(x-x_j)}{\Pi_{j!=i}(x_i-x_j)}$

$f[i][j]=f[i-1][j]*(-x_i)+f[i-1][j-1]$

O(N^2)

$f*(x-x_i)=f*x-f*x_i$也就是f平移一位，然后减掉自己原来的xi倍

posted @ 2018-12-21 20:24  *Miracle*  阅读(1272)  评论(0编辑  收藏  举报