多項式乘法
給定乙個 \(n\) 次多項式 \(f(x)\) 和乙個 \(m\) 次多項式,求出考慮直接用 \(fft\),但是值域太大,\(long\; double\) 都炸了,精度也無法保證\[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\)
直接用 \(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...