lagrange 插值法模板

2022-07-08 14:30:24 字數 3153 閱讀 6823

\[\gamma(k) = \sum_^y_i\prod_\neq }^\frac

\]

const int mod=1e9+7;

templatet qpow(t x,int k)

return e;

}templatet lagrange(int n,int x,int y,t k)

ans=(1ll*ans+1ll*y[i]*fz%mod*qpow(fm,mod-2)%mod)%mod;

}return (ans+mod)%mod;

}

當\(x_i\)​ 的取值都是連續的,可以把上面的演算法優化到o(n)複雜度

首先把\(x_i\)換成i,新的式子為

\[f(k) = \sum_^ y_i \prod_ \fracf(k)

\]對於 \(\prod_ ^\frac​\) 可以優化

對於分子來說,我們維護出關於k的字首積和字尾積,也就是

\[pre_i = \prod_^ k - j

\]\[suf_i = \prod_^n k - j

\]對於分母來說,觀察發現這其實就是階乘的形式,我們用fac[i]來表示\(i!\)

那麼式子就變成$$f(k) = \sum_^n y_i \frac$$​分母可能會出現符號問題,也就是說,當n - i為奇數時,分母應該取負號

const int mod=1e9+7;

templatet qpow(t x,int k)

return e;

}int lagrange(int n,int x,int y,int k)

return (ans+mod)%mod;

}

題目鏈結

define \(f_ = a_0+a_1 \times x^1 + a_2 \times x^2 +…+ a_n \times x^n\)

the number maybe tremendous huge, so take the module of 9999991.

for a polynomial, xh doesn't know any \(a_i\) ​ , but he knows the value of \(f_ , f_, f_…f_\) . he wants to calculate \(\displaystyle\sum_^r f_\) mod 9999991.

input

the first line contains a number \(t ( 1 \le t \le 5 )\) ——the number of test cases.

for each test case. the first line contains two integers \(n (1 \le n \le 1000)\) and \(m(1 \le m \le 2000)\).

the second line contains n+1 integers,representing the value of \(f_ , f_, f_…f_\)

​ the next mm lines, each line contains two integers l, r.

\(( 1 \le l \le r \le 9999990)\)

output

for each test case, output m lines, each line contains one integer, the value of \(isplaystyle\sum_^r f_\) mod 9999991.

樣例輸入

1 

3 21 10 49 142

6 7

95000 100000

樣例輸出
2519 

1895570

題意就是知道(0, \(f_0\)) , (1, \(f_1\)) ... (n, \(f_n\)) n+1個點,求\(s(k)=\sum_^k f(i)\)

由n+1個點可求得 \(f(n+1)\)

再由\(s(k)-s(k-1)=f(k)\)可知,\(s(k)=\sum_^k f(i)\)是n+1次多項式

且我們可以求出這n+2個點,分別是

(0, \(f_0\)) , (1, \(f_0+f_1\)), ..., (n, \(f_0+f_0+... +f_n\)), (n, \(f_0+f_0+... +f_n+f_)\)

這樣,求出\(s(k)\) 之後

\(s(r)-s(l-1)\)即為答案。

**:

#includeusing namespace std;

char buf[100000],*l=buf,*r=buf;

#define gc() l==r&&(r=(l=buf)+fread(buf,1,100000,stdin),l==r)?eof:*l++

templateinline void read(t&x)

#define init(arr,val) memset(arr,val,sizeof(arr))

const int inf=0x3f3f3f3f,mod=9999991,maxn=1020;

typedef long long ll;//鬼畜資料,只能全部用ll,不然乙個點都過不了,浪費了了我一下午。。。。

templatet qpow(t x,int k)

return e%mod;

}ll fac[maxn],ffa[maxn];

//fac是階乘

//ffa是分母,對於m次詢問,都是相同的分母,儲存起來,

//因為s(x) 已經確定,分母裡的快速冪只需求一次即可,不然坑爹資料乙個點也過不了

ll lagrange(ll n,ll x,ll y,ll k)

return (ans+mod)%mod;

}int main()

for(int i=0; i<=n; ++i)

y[n+1]=lagrange(n,x,y,n+1);//f(n+1)

x[n+1]=n+1;

for(int i=1; i<=n+1; ++i)y[i]+=y[i-1];//字首和就是s(x)個點的y值

for(int i=0; i<=n+1; ++i)

while(m--)

}return 0;

}

lagrange插值多項式

簡潔版 hanshu input 請輸入函式f x s fprintf 請輸入差值區間最小值 n xmin input fprintf 請輸入差值區間最大值 n xmax input fprintf 請輸入等分份數 n n input fprintf 請輸入自變數x n xin input h xm...

新冠插值法matlab MATLAB插值法程式

課程名稱 數學實驗 學期 2012 2013 學年第一學期 成績指導教師 李朝遷學生姓名 張偉學生學號 實驗名稱 用多種插值法逼近 sin x 實驗編號 no.實驗日期 2012 10 23 實驗學時 學院 數學與統計學院 專業 數理基礎科學年級級 一 實驗目的 學會運用插值法求得所需值。二 實驗內...

模板 拉格朗日插值法

update 其實拉格朗日插值法的問題在於求分母的複雜度是 o n 2 的,要是還要求逆元則再多乙個 logp 變成 o n 2logp 但是當乙個多項式要重複使用的時候,也不必求出他的各個係數,只要預處理出各項分母的逆元之後,o nlogp 處理分子 求出字首積和字尾積 然後再插值,漸進複雜度和求...