日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

拉格朗日插值法小结

發(fā)布時間:2024/3/24 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 拉格朗日插值法小结 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

    • 介紹
    • 拉格朗日插值法
    • 重心拉格朗日插值法
      • 例題1
        • 技巧
      • 例題2
      • 例題3
    • 練習(xí)題

介紹

眾所周知,nnn 個點 (xi,yi)(x_i,y_i)(xi?,yi?) 可以確定唯一一個 n?1n-1n?1 次的多項式。

拉格朗日插值法就是,用這 nnn 個點表示出這個多項式。

拉格朗日插值法

考慮構(gòu)造 nnn 個多項式,第 iii 個多項式 fi(x)f_i(x)fi?(x) 滿足:當 x=xix=x_ix=xi? 時,fi(x)=yif_i(x)=y_ifi?(x)=yi?,當 x=xj(j≠i)x=x_j(j\neq i)x=xj?(j?=i) 時,fi(x)=0f_i(x)=0fi?(x)=0

然后將這 nnn 個多項式加起來,就能得到一個多項式 f(x)f(x)f(x),滿足當 x=xix=x_ix=xi? 時,f(x)=yif(x)=y_if(x)=yi?;并且這是個 n?1n-1n?1 次多項式。

fi(x)f_i(x)fi?(x) 的構(gòu)造為:fi(x)=yi∏j≠ix?xjxi?xjf_i(x)=y_i\prod_{j\neq i} \dfrac {x-x_j} {x_i-x_j}fi?(x)=yi?j?=i?xi??xj?x?xj??

加起來,得到 f(x)=∑i=1nyi∏j≠ix?xjxi?xjf(x)=\sum_{i=1}^ny_i\prod_{j\neq i}\dfrac {x-x_j} {x_i-x_j}f(x)=i=1n?yi?j?=i?xi??xj?x?xj??

構(gòu)造多項式 n2n^2n2,求解一次 n2n^2n2

重心拉格朗日插值法

稍微改改上面那個柿子:
f(x)=∑i=1nyi∏j≠ix?xjxi?xjf(x)=\sum_{i=1}^n y_i\prod_{j\neq i}\dfrac {x-x_j} {x_i-x_j} f(x)=i=1n?yi?j?=i?xi??xj?x?xj??

設(shè) h=∏i=1nx?xih=\prod_{i=1}^n x-x_ih=i=1n?x?xi?,帶入得:
=h∑i=1n∏j≠iyi(xi?xj)(x?xi)=h\sum_{i=1}^n \prod_{j\neq i}\dfrac {y_i} {(x_i-x_j)(x-x_i)} =hi=1n?j?=i?(xi??xj?)(x?xi?)yi??

設(shè) ti=∏j≠iyixi?xjt_i=\prod_{j\neq i} \dfrac {y_i} {x_i-x_j}ti?=j?=i?xi??xj?yi??,帶入得:
=h∑i=1ntix?xi=h\sum_{i=1}^n \dfrac {t_i} {x-x_i} =hi=1n?x?xi?ti??

每次加入一個新點時,計算出它的 tit_iti?,并且更新別的點的 tit_iti?,時間復(fù)雜度 O(n)O(n)O(n),加入 nnn 個點就是 n2n^2n2

求解時,O(n)O(n)O(n)hhhO(n)O(n)O(n) 求出那個 ∑\sum,時間復(fù)雜度 O(n)O(n)O(n)

例題1

【模板】拉格朗日插值

寫法是重心拉格朗日插值法,雖然在這題會慢,但只是權(quán)當練習(xí)而已,無所謂了。

#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define mod 998244353int n,k; int ksm(int x,int y){int re=1;for(;(y&1?re=1ll*re*x%mod:0),y;y>>=1,x=1ll*x*x%mod);return re;} #define inv(x) ksm(x,mod-2) struct Lagrange{struct Point{int x,y,t;}d[2010];int tot=0;Lagrange(){}void insert(int x,int y){for(int i=1;i<=tot;i++)d[i].t=1ll*d[i].t*inv(d[i].x-x+mod)%mod;d[++tot]=(Point){x,y,y};for(int i=1;i<tot;i++)d[tot].t=1ll*d[tot].t*inv(x-d[i].x+mod)%mod;}int calc(int x){int prod=1,re=0;for(int i=1;i<=tot;i++){prod=1ll*prod*(x-d[i].x+mod)%mod;re=(re+1ll*d[i].t*inv(x-d[i].x+mod)%mod)%mod;}return 1ll*re*prod%mod;} }Lag;int main() {scanf("%d %d",&n,&k);for(int i=1,x,y;i<=n;i++){scanf("%d %d",&x,&y);Lag.insert(x,y);}printf("%d",Lag.calc(k)); }

技巧

有時候我們遇到的 nnn 個點的 xxx 值是連續(xù)的,下面不妨當成 xi=ix_i=ixi?=i

再看上面的柿子:
f(x)=∑i=1nyi∏j≠ix?xjxi?xj=∑i=1nyi∏j≠ix?ji?j\begin{aligned} f(x)&=\sum_{i=1}^ny_i\prod_{j\neq i}\dfrac {x-x_j} {x_i-x_j}\\ &=\sum_{i=1}^n y_i \prod_{j\neq i}\dfrac {x-j} {i-j} \end{aligned} f(x)?=i=1n?yi?j?=i?xi??xj?x?xj??=i=1n?yi?j?=i?i?jx?j??

預(yù)處理兩個數(shù)組:prei=∏j=1i(x?j),sufi=∏j=in(x?j)pre_i=\prod_{j=1}^i (x-j),suf_i=\prod_{j=i}^n (x-j)prei?=j=1i?(x?j),sufi?=j=in?(x?j),那么分子部分就是 prej?1×sufj+1pre_{j-1}\times suf_{j+1}prej?1?×sufj+1?

而分母部分不難發(fā)現(xiàn)是個階乘,即 (i?1)!(n?i)!(?1)n?i(i-1)!(n-i)!(-1)^{n-i}(i?1)!(n?i)!(?1)n?i

代入得到:
f(x)=∑i=1nyiprei?1×sufi+1(i?1)!(n?i)!(?1)n?if(x)=\sum_{i=1}^n y_i\frac {pre_{i-1}\times suf_{i+1}} {(i-1)!(n-i)!(-1)^{n-i}} f(x)=i=1n?yi?(i?1)!(n?i)!(?1)n?iprei?1?×sufi+1??

這樣在一頓預(yù)處理后也可以做到 O(n)O(n)O(n),但他的價值不止如此。

例題2

拉格朗日插值2

iii000 開始計數(shù)時,上面那個柿子就變成了 f(x)=∑i=0nyiprei?1×sufi+1i!(n?i)!(?1)n?if(x)=\sum_{i=0}^n y_i\dfrac {pre_{i-1}\times suf_{i+1}} {i!(n-i)!(-1)^{n-i}}f(x)=i=0n?yi?i!(n?i)!(?1)n?iprei?1?×sufi+1??

f(m+i)=∏j=0n(m+i?j)∑j=0nyjj!(n?j)!(?1)n?j×1m+i?jf(m+i)=\prod_{j=0}^n (m+i-j)\sum_{j=0}^n \dfrac {y_j} {j!(n-j)!(-1)^{n-j}}\times \dfrac 1 {m+i-j}f(m+i)=j=0n?(m+i?j)j=0n?j!(n?j)!(?1)n?jyj??×m+i?j1?

前面的 ∏\prod 易于處理,可以先不管,后面的 ∑\sum 是個卷積的形式,但是 mmm 高達 10810^8108,直接卷不太行。

但實際上處理方法也很簡單,原來是設(shè) Ai=yii!(n?i)!(?1)n?i,Bi=1iA_i=\dfrac {y_i} {i!(n-i)!(-1)^{n-i}},B_i=\dfrac 1 iAi?=i!(n?i)!(?1)n?iyi??,Bi?=i1?,注意到只有 [m?n,m+n][m-n,m+n][m?n,m+n] 區(qū)間內(nèi)的 BBB 是有用的,不妨將 BBB 整體左移 m?nm-nm?n 位,即 Bi=1i+m?nB_i=\dfrac 1 {i+m-n}Bi?=i+m?n1?,那么 AAABBB 得到的 CCC 中,Ci+nC_{i+n}Ci+n?fm+if_{m+i}fm+i?

代碼如下:

#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define maxn 550010 #define mod 998244353 #define bin(x) (1<<(x))int n,m,A[maxn],B[maxn]; int ksm(int x,int y){int re=1;for(;(y&1?re=1ll*re*x%mod:0),y;y>>=1,x=1ll*x*x%mod);return re;} int fac[maxn],inv_fac[maxn],inv[maxn]; void FacInit(){fac[0]=inv_fac[0]=1;for(int i=1;i<=n;i++)fac[i]=1ll*fac[i-1]*i%mod;for(int i=1;i<=n;i++)inv_fac[i]=1ll*inv_fac[i-1]*inv[i]%mod; } int w[maxn];void prep(int lg){int N=bin(lg);inv[1]=1;for(int i=2;i<=maxn-10;i++)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;for(int i=1,wn;i<N;i<<=1){w[i]=1;wn=ksm(3,(mod-1)/(i<<1));for(int j=1;j<i;j++)w[i+j]=1ll*w[i+j-1]*wn%mod;} } int r[maxn],limit; void InitR(int lg){for(int i=1;i<bin(lg);i++)r[i]=(r[i>>1]>>1)|((i&1)<<(lg-1));} int add(int x){return x>=mod?x-mod:x;} int dec(int x){return x<0?x+mod:x;} void ntt(int *f,int lg,int type=0){limit=bin(lg);if(type)reverse(f+1,f+limit);for(int i=1;i<limit;i++)if(i<r[i])swap(f[i],f[r[i]]);for(int mid=1,t;mid<limit;mid<<=1)for(int j=0;j<limit;j+=(mid<<1))for(int i=0;i<mid;i++){t=1ll*f[j+i+mid]*w[mid+i]%mod;f[j+i+mid]=dec(f[j+i]-t);f[j+i]=add(f[j+i]+t);}if(type)for(int i=0;i<limit;i++)f[i]=1ll*f[i]*inv[limit]%mod; } void NTT(int *f,int *g,int ln){int lg=ceil(log2(ln));InitR(lg);ntt(f,lg);ntt(g,lg);for(int i=0;i<bin(lg);i++)f[i]=1ll*f[i]*g[i]%mod;ntt(f,lg,1); }int main() {scanf("%d %d",&n,&m);prep(ceil(log2((n+1)<<1)));FacInit();for(int i=0,x;i<=n;i++){scanf("%d",&x);A[i]=1ll*x*inv_fac[i]%mod*inv_fac[n-i]%mod;if(n-i&1)A[i]=(mod-A[i])%mod;}for(int i=0;i<=(n<<1);i++)B[i]=ksm(m-n+i,mod-2);NTT(A,B,2*n+1);int pd=1;for(int i=0;i<=n;i++)pd=1ll*pd*(m-i)%mod;for(int i=n;i<=(n<<1);i++){A[i]=1ll*A[i]*pd%mod;printf("%d ",A[i]);pd=1ll*pd*ksm(m+i-2*n,mod-2)%mod*(m+i-n+1)%mod;} }

例題3

還有一個相當經(jīng)典的應(yīng)用:自然數(shù)冪求和,即給出 n,kn,kn,k,求 ∑i=1nik\sum_{i=1}^n i^ki=1n?ik

這是一個關(guān)于 nnnk+1k+1k+1 次多項式,證明可以看洛谷第一篇題解,寫的很好,大致思路是:一個 nnn 次多項式 f(x)f(x)f(x),假如有一個數(shù)列 f(1),f(2),f(3),...f(1),f(2),f(3),...f(1),f(2),f(3),...,將其差分后得到 f(2)?f(1),f(3)?f(2),...f(2)-f(1),f(3)-f(2),...f(2)?f(1),f(3)?f(2),... ,這個差分后的數(shù)列的每一項就變成了一個關(guān)于 iiin?1n-1n?1 次多項式。而題中的數(shù)列即為 f(i)=∑j=1ijkf(i)=\sum_{j=1}^i j^kf(i)=j=1i?jk,做差后 Δf(i)=(i+1)k\Delta f(i)=(i+1)^kΔf(i)=(i+1)k,是一個關(guān)于 iiikkk 次多項式,所以原數(shù)列是個關(guān)于 nnnk+1k+1k+1 次多項式。

考慮拉格朗日插值法,那么需要找到 k+2k+2k+2 個點值,由于這里可以自己選取點,所以為了能套用上面的技巧,選取的點就是 (1,f(1)),(2,f(2)),...,(k+2,f(k+2))(1,f(1)),(2,f(2)),...,(k+2,f(k+2))(1,f(1)),(2,f(2)),...,(k+2,f(k+2))

代入公式:
F(x)=∑i=1k+2f(i)prei?1×sufi+1(i?1)!(k+2?i)!(?1)k+2?iF(x)=\sum_{i=1}^{k+2} f(i)\frac {pre_{i-1}\times suf_{i+1}} {(i-1)!(k+2-i)!(-1)^{k+2-i}} F(x)=i=1k+2?f(i)(i?1)!(k+2?i)!(?1)k+2?iprei?1?×sufi+1??

再把 nnn 代入求值就做完了,時間復(fù)雜度 O(klog?k)O(k\log k)O(klogk)

當然也可以做到線性:注意到 iki^kik 是個完全積性函數(shù),即 ikjk=(ij)ki^kj^k=(ij)^kikjk=(ij)k,所以可以線性篩出來,那么就可以線性求 fff 了,然后階乘的逆元也是可以 O(k)O(k)O(k) 預(yù)處理的,這樣就做到了 O(k)O(k)O(k),但是比較麻煩所以下面的代碼還是寫的 O(klog?k)O(k\log k)O(klogk) 做法。

#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define maxn 1000010 #define mod 1000000007int n,k,ans=0; int ksm(int x,int y){int re=1;for(;(y&1?re=1ll*re*x%mod:0),y;y>>=1,x=1ll*x*x%mod);return re;} void add(int &x,int y){x=(x+y>=mod?x+y-mod:x+y);} void dec(int &x,int y){x=(x-y<0?x-y+mod:x-y);} int pre[maxn],suf[maxn],fac[maxn],inv_fac[maxn];int main() {scanf("%d %d",&n,&k);if(n<=k+2){for(int i=1;i<=n;i++)add(ans,ksm(i,k));}else{pre[0]=1;for(int i=1;i<=k+2;i++)pre[i]=1ll*pre[i-1]*(n-i)%mod;suf[k+3]=1;for(int i=k+2;i>=1;i--)suf[i]=1ll*suf[i+1]*(n-i)%mod;fac[0]=1;for(int i=1;i<=k+2;i++)fac[i]=1ll*fac[i-1]*i%mod;inv_fac[k+2]=ksm(fac[k+2],mod-2);inv_fac[0]=1;for(int i=k+1;i>=1;i--)inv_fac[i]=1ll*inv_fac[i+1]*(i+1)%mod;int sum=0;for(int i=1;i<=k+2;i++){add(sum,ksm(i,k));(k+2-i&1?dec:add)(ans,1ll*sum*pre[i-1]%mod*suf[i+1]%mod*inv_fac[i-1]%mod*inv_fac[k+2-i]%mod);}}printf("%d",ans); }

練習(xí)題

都是些眾所周知的題,以后要是遇到什么有趣的也會放這兒的。

[TJOI2018]教科書般的褻瀆 ? 題解
tyvj 1858 XLkxc ? 題解
[NOIP2020] 微信步數(shù) ? 題解
[集訓(xùn)隊互測2012] calc ? 題解
[JLOI2016]成績比較 ? 題解

總結(jié)

以上是生活随笔為你收集整理的拉格朗日插值法小结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 在线免费观看成年人视频 | 日韩三级黄色 | 91麻豆精品国产理伦片在线观看 | 波多野结衣一区二 | av网址在线| 日日干夜夜艹 | 欧美午夜性春猛交 | 夫妻淫语绿帽对白 | www.日本黄 | 艳妇臀荡乳欲伦交换电影 | 亚洲操操| 久久久久久国产精品免费 | 成人av高清在线 | 熟妇高潮一区二区 | 久久99国产精品久久99 | 日一日干一干 | 杏导航aⅴ福利网站 | 牛牛澡牛牛爽一区二区 | 亚洲一区二区三区婷婷 | 国产高清无密码一区二区三区 | 自拍偷拍电影 | 国产裸体永久免费视频网站 | 欧美性猛交xxxx久久久 | 免费成人看视频 | 精品一区二区久久久久久按摩 | 九九在线精品 | 性做久久久久 | 国产精品va无码一区二区三区 | 久久久久久国产视频 | 伊人久久一区二区三区 | 波多野结衣午夜 | 欧美日韩 一区二区三区 | 精品一级 | 欧美乱妇在线观看 | 天天视频亚洲 | 福利一区在线 | a级片在线看 | 久久久成人精品一区二区三区 | 综合人人 | 国产在线视频第一页 | 中文字幕25页 | 欧美日韩高清一区二区 | 打白嫩屁屁网站视频短裙 | 久久国产成人精品 | 在线免费观看一区 | 男女做的视频 | 亚洲另类xxxx | 成人中文字幕+乱码+中文字幕 | 久久国产精品一区二区 | 亚洲欧美高清视频 | 91免费高清在线观看 | 午夜视频在线观看网站 | 欧美高清视频一区二区三区 | 天天做夜夜爽 | 国产日产精品一区 | 美女视频在线免费观看 | 2018天天操| 欧美国产乱视频 | 日韩视频免费在线观看 | av无码久久久久久不卡网站 | 日本呦呦 | 拔萝卜91 | 用舌头去添高潮无码视频 | 美国美女黄色片 | 日韩欧美一区在线观看 | 在线成人免费电影 | 黄色av片三级三级三级免费看 | 欲色av| wwwwww色| aaaa一级片| 深田咏美中文字幕 | 精品免费一区二区三区 | 国产午夜伦鲁鲁 | 嫩草影院懂你的 | 日韩有码一区二区三区 | 欧美国产日韩一区二区三区 | 狠狠艹av | 国产精品无码白浆高潮 | 久久精品免费观看 | 四虎免费看黄 | 国产伦精品一区二区三区视频孕妇 | 免费在线看a | 久久久久久国产精品免费播放 | 69av网站| 中文字幕丰满人伦在线 | 国产精品老牛影院99av | 精品国产午夜 | 无码一区二区波多野结衣播放搜索 | 中国女人裸体乱淫 | 69福利视频 | 欧美伦理一区二区 | 8050午夜一级毛片久久亚洲欧 | 亚洲av中文无码乱人伦在线视色 | 国产精品久久久久久久久久久久久久久久 | 麻豆精品av | 色小说综合 | 日本黄页网址 | 久久免费黄色网址 | 国语对白久久 |