淺談切比雪夫多項式推導及其實現模版歸類


切比雪夫多項式

 

概述:

切比雪夫多項式是與棣美弗定理有關,以遞歸方式定義的一系列正交多項式序列。 通常,第一類切比雪夫多項式以符號Tn表示, 第二類切比雪夫多項式用Un表示。切比雪夫多項式 Tn 或 Un 代表 n 階多項式。

切比雪夫多項式在逼近理論中有重要的應用。這是因為第一類切比雪夫多項式的根(被稱為切比雪夫節點)可以用於多項式插值。相應的插值多項式能最大限度地降低龍格現象,並且提供多項式在連續函數的最佳一致逼近。

 

基本性質:

對每個非負整數n, Tn(x) 和 Un(x) 都為 n次多項式。 並且當n為偶(奇)數時,它們是關於x 的偶(奇)函數, 在寫成關於x的多項式時只有偶(奇)次項。

 

按切比雪夫多項式的展開式:

一個N 次多項式按切比雪夫多項式的展開式為如下,多項式按切比雪夫多項式的展開可以用 Clenshaw 遞推公式計算。第一類切比雪夫多項式由以下遞推關系確定。

 

也可以用母函數表示。

 

第二類切比雪夫多項式 由以下遞推關系給出。

 

此時母函數為

 

Clenshaw遞推公式

在數值分析中,Clenshaw遞推公式 (由Charles William Clenshaw發現)是一個求切比雪夫多項式的值的遞歸方法。

 

切比雪夫多項式

N次切比雪夫多項式,是下面形式的多項式p(x)

 

 

其中Tnn階切比雪夫多項式

 

Clenshaw遞推公式

Clenshaw遞推公式可以用來計算切比雪夫多項式的值。給定

 

 

我們定義

 

於是

 

 

(注)上面的公式在 N=0,1的情況下無意義。此時我們可以用下面的公式:

 

(downward, omit if N=0)

 

這里

或者

 

其中是第二類切比雪夫多項式

棣莫弗(de Moivre)原理

  設兩個復數(用三角形式表示)Z1=r1(cosθ1+isinθ1),Z2=r2(cosθ2+isinθ2),則:

  Z1Z2=r1r2[cos(θ1+θ2)+isin(θ1+θ2)].

解析

  證:先講一下復數的三角形式的概念。在復平面C上,用向量Z(a,b)來表示Z=a+bi.於是,該向量可以分成兩個在實軸,虛軸上的分向量.如果向量Z與實軸的夾角為θ,這兩個分向量的模分別等於rcosθ,risinθ(r=√a^2+b^2).所以,復數Z可以表示為Z=r(cosθ+isinθ).這里θ稱為復數Z的輻角.

  因為Z1=r1(cosθ1+isinθ1),Z2=r2(cosθ2+isinθ2),所以

  Z1Z2=r1r2(cosθ1+isinθ1)(cosθ2+isinθ2)

  =r1r2(cosθ1cosθ2+icosθ1sinθ2+isinθ1cosθ2-sinθ1sinθ2)

  =r1r2[(cosθ1cosθ2-sinθ1sinθ2)+i(cosθ1sinθ2+sinθ1cosθ2)]

  =r1r2[cos(θ1+θ2)+isin(θ1+θ2)].

  其實該定理可以推廣為一般形式:

推廣

  設n個復數Z1=r1(cosθ1+isinθ1),Z2=r2(cosθ2+isinθ2),……,Zn=rn(cosθn+isinθn),則:

  Z1Z2……Zn=r1r2……rn[cos(θ1+θ2+……+θn)+isin(θ1+θ2+……+θn)].

解析

  證:用數學歸納法即可,歸納基礎就是兩個復數相乘的棣莫弗定理。

  如果把棣莫弗定理和歐拉(Euler)公式“e^iθ=cosθ+isinθ”(參見《泰勒公式》,嚴格的證明需要復分析)放在一起看,則可以用來理解歐拉公式的意義。

  利用棣莫弗定理有:

  Z1Z2……Zn=r1r2……rn [cos(θ1+θ2+……+θn)+isin(θ1+θ2+……+θn)]

  如果可以把所有的復數改寫成指數的形式,即:Z1=r1e^iθ1,Z2=r2e^iθ2,……,Zn=rne^iθn,

  Z1Z2……Zn=r1r2……rn e^i(θ1+θ2+……+θn)

  這和指數的可加性一致.

  在一般形式中如果令Z1=Z2=……=Zn=Z,則能導出復數開方的公式.有興趣可自己推推看.

下面這題可作為切比雪夫多項式的模版:

Trig Function

TimeLimit: 2000/1000 MS (Java/Others)    Memory Limit:32768/32768 K (Java/Others)
Total Submission(s): 714    Accepted Submission(s): 206

Problem Description

 

f(cos(x))=cos(n∗x) holds for all x.

Given two integersn and m , you need to calculate the coefficient of x^m​​ in f(x), modulo 998244353

 

  

Input

 

Multiple testcases (no more than 100).

Each test casecontains one line consisting of two integers n and m.

1≤n≤109,0≤m≤104

 

  

Output

Output the answerin a single line for each test case.

  

Sample Input

2 0

2 1

2 2

 

Sample Output

998244352

0

2


【題意】

給出一個函數,代入n,m后求出xm的系數,並取模輸出。


【思路】


我們先嘗試把cos(nx)化為cos(x)的形式,然后把cos(x)用x代換,就可以得到f(x)=...的形式,然后就能得到所求的系數了。


那么我們如何把cos(nx)化為cos(x)的形式呢。


其實可以嘗試着暴力寫出前幾項的形式。如下圖:

 

由寫出的式子,我們可以發現以下幾點:

  1. 當m大於n時,答案顯然為0。
  2. 當n為奇數且m為偶數或n為偶數且m為奇數時答案顯然為0。
  3. 當n為奇數,且m為1時,答案的絕對值為n。
  4. 當n為偶數,且m為0時,答案的絕對值為1。
  5. 其余情況答案的絕對值均為【 n * (n-m+2) * (n-m+4) * ... * (n+m-4) * (n+m-2) 】/(m!)。(注意逆元的運用)
  6. 上面出現絕對值的情況,3和4 當(n/2)%2 == 0 時符號為正,否則為負;5 當((n-m)/2)%2 == 0時,符號為正,否則符號為負。

依照這個規律分類討論一下即可。

於是我們可以得到以下一般解析式

注意"!!"不是階乘的階乘,而是不超過n且與n具有相同奇偶性的所有正整數連乘積。

n分類討論下,當n為偶數時m=2*k, n為奇數時m=2*k-1

還有注意下"!!"的約分,可能下面的比上面的大

於是我們就得到了以下代碼:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=1e5+5;
 5 const int mod=998244353;
 6 ll fac[maxn]={1};
 7 ll n,m;
 8 void init()
 9 {
10     for(int i=1;i<maxn;i++)
11         fac[i]=fac[i-1]*i%mod;
12 }
13 ll qmod(ll x,int q)
14 {
15     ll res=1;
16     while(q)
17     {
18         if(q%2)
19             res=res*x%mod;
20         x=x*x%mod;
21         q/=2;
22     }
23     return res;
24 }
25 int main(void)
26 {
27     init();
28     while(~scanf("%lld%lld",&n,&m))
29     {
30         if(m>n)
31             puts("0");
32         else if(n%2&&m%2==0)
33             puts("0");
34         else if(n%2==0&&m%2)
35             puts("0");
36         else
37         {
38             ll fz=n%mod;
39             if(m>=1)
40             {
41                 for(int i=n-m+1;i<=n+m-1;i++)
42                 {
43                     if(i%2==(n+m-2)%2)
44                     {
45                         fz=fz*i%mod;
46                     }
47                 }
48                 ll tmp=fz*qmod(fac[m],mod-2)%mod;
49                 if((n-m)/2%2)
50                     tmp=-tmp;
51                 printf("%lld\n",(tmp+mod)%mod);
52             }
53             else
54             {
55                 ll t=1;
56                 for(int i=n+m-1;i<=n-m;i++)
57                 {
58                     if(i%2==(n+m-2)%2)
59                         t=t*i%mod;
60                 }
61                 ll tmp=fz*qmod(fac[m],mod-2)%mod*qmod(t, mod-2)%mod;
62                 if((n-m)/2%2)
63                     tmp=-tmp;
64                 printf("%lld\n",(tmp+mod)%mod);
65             }
66         }
67     }
68 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM