兩個多項式,求它們的乘積模\(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\)就是\(sqq\),\(c*d\)就是\(1\)。這樣下來要跑\(7\)次\(\text\),很慢但是能過,而且要開\(\text\)和預處理單位根不然會被卡精度。
有乙個比較快的方法是變成兩個複數多項式\(e[x]=a[x]+b[x]*i,f[x]=c[x]+d[x]*i\)(其中\(i\)表示\(\sqrt\))。然後乘起來做一下公式就可以做到\(3\)次\(\text\)。
還有乙個就是不會被卡精度的\(\text\)方法,就是找三個有原根的模數分別跑出來,然後用\(\text\)合併,這個跑的次數多,但是因為是\(\text\)所以常數和第乙個差不多?
時間複雜度都是\(o(n\log n)\)就是常數有不同而已
#include#include#include#include#define ll long long
using namespace std;
const ll n=4e5+10,sqq=32768;
const long double pi=acos(-1);
struct complex
}a[n],b[n],c[n],d[n];
complex operator+(complex a,complex b)
complex operator-(complex a,complex b)
complex operator*(complex a,complex b)
ll n,m,p,f[n],g[n],h[n],r[n];
complex w[n];
void fft(complex *f,ll op,ll n)
fft(a,-1,n);fft(b,-1,n);fft(c,-1,n);
for(ll i=0;ireturn;
}signed main()
P4245 模板 任意模數多項式乘法
首先這類問題指的是對於乙個非ntt模數,我們如何計算多項式乘法,對於ntt不容易找到單位根,對於fft又會爆精度。方法1 三模數ntt 尋找三個大模數最後crt合併即可 方法2 mtt 將係數拆分為兩部分,分別是m的倍數和餘數,然後我們只需要對其分別處理即可,但是這樣暴力的做一共需要7次fft複雜度...
P4245 模板 任意模數多項式乘法
首先這類問題指的是對於乙個非ntt模數,我們如何計算多項式乘法,對於ntt不容易找到單位根,對於fft又會爆精度。方法1 三模數ntt 尋找三個大模數最後crt合併即可 方法2 mtt 將係數拆分為兩部分,分別是m的倍數和餘數,然後我們只需要對其分別處理即可,但是這樣暴力的做一共需要7次fft複雜度...
洛谷P4245 模板 任意模數多項式乘法
給定 2 個多項式 f x g x 請求出 f x g x 係數對 p 取模,且不保證 p 可以分解成 p a cdot 2 k 1 之形式。n leq 10 5 a,b leq 10 9 p leq 10 9 9 不保證 p 是 ntt 模數,所以不能直接用 ntt 做。一般有兩種處理方法,一是用...