拉格朗日插值法

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了拉格朗日插值法相关的知识,希望对你有一定的参考价值。

拉格朗日插值法

重心拉格朗日插值法

gu

拉插板子

cal 离散点拉插 O ( n 2 ) O(n^2) O(n2)

inpo 连续点拉插 O ( n ) O(n) O(n)

//Lagrange Interpolation 
#define il inline
il ll ksm(ll a,ll n,ll m=mod){ll s=1;while(n){if(n&1) s=s*a%m;a=a*a%m;n>>=1;}return s;}
struct LR{
	ll x[N],y[N];int n;
	ll fac[N+5],facinv[N+5],inv[mod+5];
	il ll Inv(ll n){return ksm(n,mod-2);}
	il void init(){	//预处理阶乘和阶乘逆元,逆元.
		fac[0]=inv[0]=inv[1]=1;for(int i=1;i<=N;i++) fac[i]=fac[i-1]*i%mod;
		facinv[N]=Inv(fac[N]);
		for(int i=N-1;~i;i--) facinv[i]=facinv[i+1]*(i+1)%mod;
		for(int i=2;i<mod+5;i++)
			inv[i]=(mod-mod/i)*inv[mod%i]%mod;
	}
	il ll cal(ll k){	//离散点n个点[0,n-1] x[i],y[i] 插f(k)
		ll s=0;
		for(int i=0;i<n;i++){
			ll p=y[i]%mod,q=1;
			for(int j=0;j<n;j++){
				if(i==j) continue;
				p=p*(k-x[j])%mod;
				q=q*(x[i]-x[j])%mod;
			}
			s=(s+p*Inv(q)%mod)%mod;
		}return (s%mod+mod)%mod;
	}
	il ll inpo(ll *f,int n,ll x){	//给定 连续i属于[0,n] f(i) 拉插f(x)
		ll c=1,p,s=0;
		for(int i=0;i<=n;i++) c=c*(x-i)%mod;
		for(int i=0;i<=n;i++){
			p=c*inv[x-i]%mod*facinv[n-i]%mod*facinv[i]%mod;
			if((n-i)&1)  s=(s-p*f[i]%mod)%mod;
			else s=(s+p*f[i]%mod)%mod;
		}
		return (s%mod+mod)%mod;
	}
}L;

连续插值板子

对于一个 n n n次多项式。

连续插值 x ∈ [ 0 , n ] x\\in [0,n] x[0,n]

f k = ∑ i = 0 n f i ∏ j ≠ i k − j i − j \\large f_k=\\sum\\limits_{i=0}^n f_i \\prod\\limits_{j\\neq i}\\dfrac{k-j}{i-j} fk=i=0nfij=iijkj

先提出来没有 k k k ∏ j ≠ i 1 i − j \\large \\prod\\limits_{j\\ne i}\\dfrac{1}{i-j} j=iij1

拆开: ∏ j ≠ i ( − 1 ) n − i i ! ( n − i ) ! \\large \\prod\\limits_{j\\ne i}\\dfrac{(-1)^{n-i}}{i! (n-i)!} j=ii!(ni)!(1)ni

分子先预处理出所有的 c = ∏ i = 0 n ( k − i ) \\large c=\\prod\\limits_{i=0}^{n}(k-i) c=i=0n(ki)

f k = ∑ i = 0 n f i ∏ j ≠ i k − j i − j = ∑ i = 0 n f i c i ! ( n − i ) ! ( − 1 ) n − i ( k − i ) \\large f_k=\\sum\\limits_{i=0}^n f_i \\prod\\limits_{j\\neq i}\\dfrac{k-j}{i-j}=\\sum\\limits_{i=0}^n f_i \\dfrac{c}{i!(n-i)!(-1)^{n-i}(k-i)} fk=i=0nfij=iijkj=i=0nfii!(ni)!(1)ni(ki)c

预处理出阶乘逆元 f a c i n v ( i ) facinv(i) facinv(i)​ 和数的逆元 i n v ( i ) inv(i) inv(i)​。

注意 i n v ( k − i ) inv(k-i) inv(ki) k k k很大是预处理不了的,只能费马小定理或者 e x g c d exgcd exgcd

时间复杂度: O ( n ) O(n) O(n)

	il ll inpo(ll *f,int n,ll x){	//给定 连续i属于[0,n] f(i) 拉插f(x)
		ll c=1,p,s=0;
		for(int i=0;i<=n;i++) c=c*(x-i)%mod;
		for(int i=0;i<=n;i++){
			p=c*inv[x-i]%mod*facinv[n-i]%mod*facinv[i]%mod;
			if((n-i)&1)  s=(s-p*f[i]%mod)%mod;
			else s=(s+p*f[i]%mod)%mod;
		}
		return (s%mod+mod)%mod;
	}
使用费马小定理求inv(x-i)
	il ll inpo(ll *f,int n,ll x){	//给定 连续i属于[0,n] f(i) 拉插f(x)
		ll c=1,p,s=0;
		for(int i=0;i<=n;i++) c=c*(x-i)%mod;
		for(int i=0;i<=n;i++){
			p=c*Inv(x-i)%mod*facinv[n-i]%mod*facinv[i]%mod;
			if((n-i)&1)  s=(s-p*f[i]%mod)%mod;
			else s=(s+p*f[i]%mod)%mod;
		}
		return (s%mod+mod)%mod;
	}

习题

2019 ICPC 邀请赛(南昌) B-Polynomial

https://nanti.jisuanke.com/t/40254

考虑如何快速求出 S ( n ) = ∑ i = 0 n f ( i ) S(n)=\\sum\\limits_{i=0}^n f(i) S(n)=i=0nf(i)

以上是关于拉格朗日插值法的主要内容,如果未能解决你的问题,请参考以下文章

拉格朗日插值方法

python拉格朗日插值

拉格朗日插值法求2的平方根

拉格朗日插值公式

拉格朗日插值法理论误差怎么得的

拉格朗日插值公式