多點求值與快速插值

2022-09-01 04:36:11 字數 3199 閱讀 4214

多點求值

給出 $n$ 次多項式 $a(x)$ ,求出 $m$ 個 $x_i$ 對應的 $a(x_i)$

考慮分治,設 $l(x)=\prod_^}(x-x_i)$ , $r(x)=\prod_+1}^n(x-x_i)$

對於 $i \in [1,\frac],f(x_i)=(f \mod l)(x_i)$ , 對於 $i \in (\frac,n],f(x_i)=(f \mod r)(x_i)$

就是對於左半部分來說, $f(x)=l(x)q(x)+r(x)$ ,把 $x_i$ 帶入後只剩下了 $r(x)$ 的部分,右半部分也同理

於是我們在 $o(nlog^2n)$ 完成了多點求值

快速插值

考慮拉格朗日插值: $f(x)=\sum_^n\frac(x-x_j)}(x_i-x_j)}y_i$

如果暴力做的話只能做到 $o(n^2)$ ,考慮怎樣優化

下面的部分是個常數,設 $m(x)=\prod_^n(x-x_i)$ ,考慮對於每個 $i$ , 下面的式子相當於 $\frac$ 帶入 $x_i$ 之後的值,但是出現了 $\frac$ , 根據洛必達法則,它的值相當於 $m'(x)$ 帶入 $x_i$ 後的值,於是可以分治+ $ntt$ 後求導,再多點求值求出每個 $x_i$ 對應的值

於是 $f(x)=\sum_^n\prod_(x-x_j)v_i$ , 這一部分就可以遞迴處理

設 $l(x)=\prod_^}(x-x_i)$ , $r(x)=\prod_+1}^n(x-x_i)$,

於是 $f(x)=r(x)\sum_^}v_i\prod_^}[j \ne i](x-x_j)+l(x)\sum_+1}^v_i\prod_+1}^[j \ne i](x-x_j)$

於是我們在 $o(nlog^2n)$ 完成了快速插值

**

#include #define _(d) while(d(isdigit(c=getchar())))

using

namespace

std;

intrd()

int vv[20

];void wr(int

x)

int v=0;while(x) vv[++v]=x%10,x/=10

;

for (int i=v;i;i--) putchar(vv[i]^48);}

const

int n=4e5+5,p=998244353

;int a[n],b[n],t,p,re[n],c[n],d[n],e[n],g[2][19][n],c[n],*d[n],e[n],*f[n],g[n],*h[n];

int x(int x)

int k(int x,int

y)void

init()

}void pre(int

l)void ntt(int *a,int

o)

if(o)

for (int i=0,v=k(t,p-2);i)

a[i]=1ll*a[i]*v%p;

}void dao(int *a,int

l)void inv(int *a,int *b,int

l) inv(a,b,(l+1)>>1

);

for (int i=0;i)

a[i]=a[i],b[i]=b[i];

pre(l

<<1);ntt(a,0);ntt(b,0

);

for (int i=0;i)

a[i]=1ll*a[i]*b[i]%p*b[i]%p;

ntt(a,1);

for (int i=0;i)

b[i]=x(x(b[i]<<1)+p-a[i]);

for (int i=0;i0;}

void dvs(int *f,int *g,int *q,int *d,int n,int

m)#define ls k<<1

#define rs k<<1|1

#define mid ((l+r)>>1)

void build(int k,int l,int

r) build(ls,l,mid);build(rs,mid+1

,r);

c[k]=c[ls]+c[rs];

d[k]=new

int[c[k]+1

];

for (int i=0;i<=c[ls];i++) a[i]=d[ls][i];

for (int i=0;i<=c[rs];i++) b[i]=d[rs][i];

pre(c[k]+2);ntt(a,0);ntt(b,0

);

for (int i=0;ip;

ntt(a,1);

for (int i=0;i<=c[k];i++) d[k][i]=a[i];

for (int i=0;i0;}

void push(int k,int

l)void qry(int k,int l,int

r) push(ls,c[ls]-1);push(rs,c[rs]-1

); dvs(f[k],d[ls],c,f[ls],e[k],c[ls]);

for (int i=0;i<=e[k]-c[ls];i++) c[i]=0

; dvs(f[k],d[rs],c,f[rs],e[k],c[rs]);

for (int i=0;i<=e[k]-c[rs];i++) c[i]=0

; qry(ls,l,mid);qry(rs,mid+1

,r);

}void multip(int *a,int n,int *b,int

m)void work(int k,int x,int y,int l,int

r)void calcf(int k,int l,int

r) calcf(ls,l,mid);calcf(rs,mid+1

,r);

g[k]=r-l;h[k]=new

int[r-l+1

]; work(k,ls,rs,l,r);work(k,rs,ls,l,r);

}void insv(int *a,int *b,int

n)int

n,a[n],b[n];

intmain()

多點求值與暴力插值

給你 n 個點 x i,y i 要求求出這個 n 1 次多項式 f x 我們有 f x sum ny i frac x x j x i x j 感性愉悅認識一下這個拉格朗日插值 複雜度 o n 2 給你 x 和 乙個 n 次多項式 a 要求求出 y 將需要求的點值分成兩個子任務 x 1 rfloor...

快速畫素混合插值

用python實現的乙個象素插值demo程式,象素混合累積差插值,和qq上乙個朋友聊影象拼接時,寫的演示程式。確切地說,並未用到影象學的知名演算法,實際效果還行,理論效果有待驗證。主要原理是圖形學中累積快取差 計算機網路中的二元指數退避。coding gbk import math import i...

插值與擬合

插值 插值是相對擬合略微麻煩一點點 插值的函式 interp2,這個大家經常見,關於interp2的用法網上介紹的很多。這裡有乙個需要注意的事項就是 以下為例 x0 1200 400 4000 y0 1200 400 3600 z0 1130 1250 1280 1230 1040 900 500 ...