任意模數多項式乘法

2022-02-01 18:28:11 字數 1641 閱讀 4498

多項式乘法

給定乙個 \(n\) 次多項式 \(f(x)\) 和乙個 \(m\) 次多項式,求出

\[f(x)\times g(x)

\]係數對 \(p\) 取模,且不保證\(p\) 可以分解成 \(p=2^ka+1\) 之形式,\(0\leq a_i,b_i\leq 10^9\),\(2\leq p\leq 10^9+9\)

考慮直接用 \(fft\),但是值域太大,\(long\; double\) 都炸了,精度也無法保證

直接用 \(ntt\),但是是任意模數,根本用不了

處理這種問題,我們常有兩種做法:

三模ntt

都 \(1202\) 年了,不會還有人寫三模 \(ntt\) 吧

好吧,其實是我不會

另一種比較常用的做法是

mtt既然 \(fft\) 處理不了值域很大的情況,我們就從問題入手,將值域縮小

不妨將兩個多項式拆成:

\[f(x)=m\times a(x)+b(x)

\]\[g(x)=m\times c(x)+d(x)

\]當 \(m=2^\) 時,可以完美避免炸 \(double\) 的問題

現在問題就轉化為了

\[(m\times a(x)+b(x))\times (m\times c(x)+d(x))

\]\[m^2a(x)c(x)+m(b(x)c(x)+a(x)d(x))+b(x)d(x)

\]所以直接 \(7\) 次 \(fft\) 就解決啦

\(ps\):可以省到 \(4\) 次 \(fft\),但是我還不會

**

#include #include #include #include #include typedef long long ll;

typedef unsigned long long ull;

using namespace std;

const int maxn = 3e5 + 50, inf = 0x3f3f3f3f;

const double pi = acos (-1);

inline int read ()

inline void write (register int x)

int n, m, m, mod, len = 1, bit;

int rev[maxn], f[maxn];

struct complex

complex (register double a, register double b)

inline complex operator + (const complex &a) const

inline complex operator - (const complex &a) const

inline complex operator * (const complex &a) const

} g[maxn], a[maxn], b[maxn], c[maxn], d[maxn], omega[maxn];

inline void fft (register int len, register complex * a, register int opt)

} }}int main ()

任意模數多項式乘法逆

蒟蒻 thesure 剛剛打了任意模數多項式乘法逆的板子 然後 lin4xu 扔來乙個多項式 f x 並 讓 thesure 求出它乘法逆的 x n 項係數對mod取模的結果 lin4xu 知道 thesure 很菜,所以並不想難為 thesure 1.多項式的最高次數不會超過 10 2.f 0 1...

P4245 模板 任意模數多項式乘法

首先這類問題指的是對於乙個非ntt模數,我們如何計算多項式乘法,對於ntt不容易找到單位根,對於fft又會爆精度。方法1 三模數ntt 尋找三個大模數最後crt合併即可 方法2 mtt 將係數拆分為兩部分,分別是m的倍數和餘數,然後我們只需要對其分別處理即可,但是這樣暴力的做一共需要7次fft複雜度...

P4245 模板 任意模數多項式乘法

兩個多項式,求它們的乘積模 p 方法好像挺多,我用的是最簡單的一種就是,先定乙個常數 sqq 一般是 sqrt q 把乙個項的數 x 拆成 k sqq r 然後把 f 的 k 丟進 a r 丟進 b g 的 k 丟進 c r 丟進 d 然後對於 a c 的部分就是 sqq 2 的部分,a d b c...