在数值分析中,拉格朗日插值法是以法国十八世纪数学家约瑟夫·拉格朗日命名的一种多项式插值方法。许多实际问题中都用函数来表示某种内在联系或规律,而不少函数都只能通过实验和观测来了解。如对实践中的某个物理量进行观测,在若干个不同的地方得到相应的观测值,拉格朗日插值法可以找到一个多项式,其恰好在各个观测的点取到观测到的值。这样的多项式称为拉格朗日(插值)多项式。数学上来说,拉格朗日插值法可以给出一个恰好穿过二维平面上若干个已知点的多项式函数。拉格朗日插值法最早被英国数学家爱德华·华林于1779年发现,不久后(1783年)由莱昂哈德·欧拉再次发现。1795年,拉格朗日在其著作《师范学校数学基础教程》中发表了这个插值方法,从此他的名字就和这个方法联系在一起。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=9999991;
ll a[1010],sum[1010],fact[1010],pre[1010],suff[1010],finv[1010];
ll quickpow(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1)
res=(res*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return res%mod;
}
void init()
{
fact[0]=1;
int i,j,k;
for(i=1;i<1010;i++)
{
fact[i]=fact[i-1]*i%mod;
}
finv[1009]=quickpow(fact[1009],mod-2);
for(i=1008;i>=0;i--)
{
finv[i]=finv[i+1]*(i+1)%mod;
}
}
ll solve(ll hh[],ll n,ll x)
{
if(x<=n)
return hh[x];
int i,j,k;
pre[0]=1,suff[n]=1;
int ans=0;
for(int i=1;i<=n;i++)
pre[i]=ll(pre[i-1]*(x-(i-1)))%mod;
for(int i=n-1;i>=0;i--)
suff[i]=ll(suff[i+1]*(x-(i+1)))%mod;
for(int i=0;i<=n;i++)
{
int fuhao=(n-i)&1?-1:1;
ans+=hh[i]%mod*fuhao*pre[i]%mod*suff[i]%mod*finv[i]%mod*finv[n-i]%mod;
ans=(ans%mod+mod)%mod;
}
return ans;
}
int main()
{
init();
int T;
scanf("%d",&T);
while(T--)
{
int n,m,i,j;
scanf("%d %d",&n,&m);
for(i=0;i<=n;i++)
{
scanf("%d",&a[i]);
}
a[n+1]=solve(a,n,n+1);
sum[0]=a[0];
for(i=1;i<=n+1;i++)
{
sum[i]=(sum[i-1]+a[i])%mod;
}
while(m--)
{
int left,right;
scanf("%d %d",&left,&right);
ll ans=(solve(sum,n+1,right)-solve(sum,n+1,left-1));
ans=(ans%mod+mod)%mod;
printf("%lld\n",ans);
}
}
return 0;
}
参考文献:
拉格朗日插法的应用(ACM,2019南昌邀请赛B题)_hash[072]的博客-CSDN博客
牛客网暑期ACM多校训练营(第一场) F Sum of Maximum(组合数学,拉格朗日插值)_czdb的博客-CSDN博客