定义
一般地,若已知 (y=f(x)), 在互不相同 (n+1) 个点:(x_0,x_1,dots x_n) 处的函数值:(y_0,y_1,dots y_n) ,即该函数过点:((x_0,y_0),(x_1,y_1),dots (x_n,y_n)) ,则可以考虑构造一个过这 (n+1) 个点的,最高次幂不超过 (n) 的多项式:
使其满足:
定理
满足插值条件的,次数不超过 (n) 的多项式是存在而且是唯一的。
分析
可以理解为,将该多项式 (P_n(x)) 拆成 (n+1) 个函数的和的形式:
其中,第 (i) 个函数 (f_i(x)) 满足除 (f_i(x_i)=y_i) 外,其它位置取值都为 (0)。即:
代入 (f(x_i)=y_i),可以得出:
即插值公式为:
另外,还有拉格朗日插值的优化:重心拉格朗日。
https://www.cnblogs.com/ECJTUACM-873284962/p/6833391.html
Polynomial-2019南昌邀请赛
题意
定义(f(x)=a_0+a_1 imes x^1+a_2 imes x^2+dots +a_n imes x^n),现在已知 (f_{(0)},f_{(1)},f_{(2)},dots ,f_{(n)}),现在要求:
题目链接:https://nanti.jisuanke.com/t/40254
分析
根据拉格朗日插值的公式,可以得出 (f(x)) 的通项:
其中常数项部分,可以通过通过阶乘和逆元预处理出来,注意 (-1)。而后面与 (x) 有关的项,可以代入 (x) 通过前缀积和后缀积求出。
但是如果要求一段区间内的函数值之和,可以考虑求出前缀和。因为 (n) 次多项式的前缀和是 (n+1) 次多项式,且前缀和需要 (n+1) 个点来求出。因此,可以利用 (f(x)) 求出 (f(n+1)) ,从而求出前缀和的多项式在各点的取值,进而求出前缀和的多项式,求差即可。
代码
#include<bits/stdc++.h>
//先求Pn的多项式,然后求其前缀和的多项式
using namespace std;
typedef long long ll;
const int mod=9999991;
const int N=1e3+10;
const int M=1e7+5;
ll fact[N],sum[M],inv[N],pre[N],suf[N],f[N];
ll power(ll x,ll y)
{
ll res=1;
x%=mod;
while(y)
{
if(y&1) res=res*x%mod;
x=x*x%mod;
y>>=1;
}
return res;
}
void init()
{
int maxn=1000;
fact[0]=1;
for(int i=1;i<=maxn;i++)
fact[i]=1LL*fact[i-1]*i%mod;
inv[maxn]=power(fact[maxn],mod-2);
for(int i=maxn-1;i>=0;i--)
inv[i]=1LL*inv[i+1]*(i+1)%mod;
}
ll solve(ll h[],int x,int n)//求出对应的函数值
{
if(x<=n) return h[x];
ll res=0;
pre[0]=x,suf[n]=(x-n);
for(int j=1;j<=n;j++)
pre[j]=1LL*pre[j-1]*(x-j)%mod;
for(int j=n-1;j>=0;j--)
suf[j]=1LL*suf[j+1]*(x-j)%mod;
for(int i=0;i<=n;i++)
{
ll tmp=h[i];
tmp=tmp*inv[n-i]%mod*inv[i]%mod;
int flag=((n-i)%2?-1:1);
tmp=tmp*flag%mod;
if(i>0) tmp=tmp*pre[i-1]%mod;
if(i<n) tmp=tmp*suf[i+1]%mod;
res=(res+tmp+mod)%mod;
}
return res;
}
int main()
{
int T,L,R,n,m;
scanf("%d",&T);
init();
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++)
scanf("%lld",&f[i]);
f[n+1]=solve(f,n+1,n);
sum[0]=f[0];
for(int i=1;i<=n+1;i++)
sum[i]=(sum[i-1]+f[i])%mod;
while(m--)
{
scanf("%d%d",&L,&R);
printf("%lld
",(solve(sum,R,n+1)-solve(sum,L-1,n+1)+mod)%mod);
}
}
return 0;
}