多項式乘法運算終極版

2021-06-25 09:56:40 字數 2206 閱讀 2978

介紹了用快速傅利葉變

換來求多項式的乘法。可以發現它是利用了單位復根的特殊性質,大大減少了運算,但是這種做法是對複數係數的矩陣

加以處理,每個複數係數的實部和虛部是乙個正弦及余弦函式,因此大部分係數都是浮點數,我們必須做複數及浮點數

的計算,計算量會比較大,而且浮點數的計算可能會導致誤差增大。

今天,我將來介紹另一種計算多項式乘法的演算法,叫做快速數論變換(ntt),在離散正交變換的理論中,已經證明在

複數域內,具有迴圈卷積特性的唯一變換是dft,所以在複數域中不存在具有迴圈卷積性質的更簡單的離散正交變換。

因此提出了以數論為基礎的具有迴圈卷積性質的快速數論變換

回憶複數向量,其離散傅利葉變換公式如下

離散傅利葉逆變換公式為

今天的快速數論變換(ntt)是在快速傅利葉變換(fft)中,通過

快速數論變換來說,則是可以將

的原根(由於是素數,那麼原根一定存在)。即

所以綜上,我們得到數論變換的公式如下

數論變換的逆變換公式為

這樣就把複數對應到乙個整數,之後一切都是在

上述數論變換(ntt)公式中,要求

由於2的方冪,所以可以構造形

費馬素數,這樣的變換叫做費馬數數論變換

這裡我們選擇

題目:

分析:題目意思就是大數相乘,此處用快速數論變換(ntt)實現。

**:

#include #include #include using namespace std;

typedef long long ll;

const int n = 1 << 18;

const int p = (479 << 21) + 1;

const int g = 3;

const int num = 20;

ll wn[num];

ll a[n], b[n];

char a[n], b[n];

ll quick_mod(ll a, ll b, ll m)

b >>= 1;

a = a * a % m;

}return ans;

}void getwn()

}void prepare(char a, char b, ll a, ll b, int &len)

}void rader(ll a, int len)

if(j < k) j += k;

}}void ntt(ll a, int len, int on)}}

if(on == -1)

}void conv(ll a, ll b, int n)

void transfer(ll a, int n)

else t = 0;

}}void print(ll a, int n)

else if(!flag)

putchar(a[i] + '0');

}puts("");

}int main()

return 0;

}

多項式乘法

時間限制 c c 1秒,其他語言2秒 空間限制 c c 262144k,其他語言524288k 64bit io format lld et reo 吃完了元宵,又開始思考數學問題了。這次他拿了兩個多項式 p mathscrp 和 q mathscrq 他知道這兩個多項式的乘積也是乙個多項式,但他不...

多項式乘法

l1和l2是兩個帶頭結點的單鏈表表示的多項式,編寫演算法計算兩個多項式的乘積,運算結果仍用單鏈表進行儲存 include using namespace std typedef struct lnode lnode,linkedlist 查詢計算結果應該插入的位置 param l 鍊錶的頭結點指標 ...

多項式加法 乘法

學校acm上面的題目,題目不難,不少細節。本質就是鍊錶操作,首先是題目要求 輸入 兩組資料,每一組代表乙個一元整係數多項式,有多行組成,其中每一行給出多項式每一項的係數和指數,這些行按指數遞減次序排序,每一組結束行為 0 1 輸出 三組資料,前兩組為一元整係數多項式,最後一組為兩個多項式的和。一元整...