拉格朗日插值

 

作用

给定一个n次多项式fn+1个点值,在O(n*n)的时间复杂度内求出fx)的值。

(一般应先对式子进行推导,展开,确定其为以什么为自变量的多项式)

经典应用如求    

这就是一个以n为底的k+2次多项式。例题:https://www.luogu.org/problemnew/show/CF622F

#include<cstdio>
#include<iostream>
#include<ctype.h>
using namespace std;
#define ll long long
inline ll rd()
{
    ll x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-f;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return x*f;
}
const int N=1e6+13,P=1e9+7;
ll fac[N],y[N];
ll ksm(ll x,ll n){ll ans=1;for(;n;n>>=1,x=x*x%P)if(n&1)ans=ans*x%P;return ans;}
int main()
{
    int n=rd(),k=rd();fac[0]=1;ll g=n,ans=0,a,b;
    for(int i=1;i<=k+1;i++) fac[i]=fac[i-1]*i%P,g=g*(n-i)%P;
    for(int i=1;i<=k+1;i++) y[i]=y[i-1]+ksm(i,k),y[i]=y[i]<P?y[i]:y[i]-P;
    if(n<=k+1){printf("%lld",y[n]);return 0;}
    for(int i=0;i<=k+1;i++) 
    {
        b=fac[i]*fac[k+1-i]%P*(n-i)%P;if((k+1-i)&1)b=P-b;
        b=ksm(b,P-2)*y[i]%P,ans+=b,ans=ans<P?ans:ans-P;
    }
    printf("%lld",ans*g%P);
}

公式

模板 

P4781 【模板】拉格朗日插值 - 洛谷 | 计算机科学教育新生态
https://www.luogu.org/problemnew/show/P4781

#include<cstdio>
#include<iostream>
#include<ctype.h>
#include<cmath>
using namespace std;
#define ll long long
inline ll rd()
{
    ll x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-') f=-f;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return x*f;
}
const int P=998244353;
int a[2003],b[2003];
ll KSM(ll x,int n)
{
    ll ans=1;
    while(n){if(n&1) (ans*=x)%=P;(x*=x)%=P;n>>=1;}
    return ans;
}
ll ans=0;
int main()
{
    int n=rd(),K=rd();
    for(int i=1;i<=n;i++) a[i]=rd(),b[i]=rd();
    for(int i=1;i<=n;i++)
    {
        ll p=1,q=1;
        for(int j=1;j<=n;j++) if(i!=j) (q*=(K-a[j]))%=P,(p*=(a[i]-a[j]))%=P;
        (ans+=q*KSM(p,P-2)%P*b[i]%P)%=P;
    }
    if(ans<0) ans+=P;
    printf("%lld",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/LWL--Figthing/p/10594839.html