多項式板子 新

2022-05-27 16:33:09 字數 3168 閱讀 8432

upd於2.19:拉格朗日反演、多項式倍增快速冪

(好像是還差乙個多項式取模...)算了不寫了

注意本板子使用過程中:每個函式傳的len一定要保證是2的倍數,並且傳遞的陣列需要保證他有多於2*len的空間

每個函式傳進來的指標保證[0,len)有值,[len,2*len)有定義

注意new出來的記憶體一定要清零,不然肯定會炸

#include #include using namespace std;

const int p = 998244353;

int qpow(int x, int y)

return res;

}void ntt(int *a, int len, int flag)

} if (flag == -1)

delete r;

}void poly_inv(int *a, int len)

int len1 = len / 2;

int *f0 = new int[len * 2];

for (int i = 0; i < len1; i++) f0[i] = a[i];

for (int i = len1; i < len * 2; i++) f0[i] = 0;

poly_inv(f0, len1);

for (int i = len1; i < len * 2; i++) f0[i] = 0;

ntt(f0, len * 2, 1), ntt(a, len * 2, 1);

for (int i = 0; i < len * 2; i++) a[i] = ((2 * f0[i] % p - a[i] * (long long)f0[i] % p * f0[i] % p) % p + p) % p;

ntt(a, len * 2, -1);

for (int i = len; i < len * 2; i++) a[i] = 0;

delete f0;

}void poly_derivation(int *a, int len)

void poly_intergal(int *a, int len)

void poly_ln(int *a, int len)

//這裡本來應該打二次剩餘的,但是因為那道題只有常數項為1的情況,就寫了暴力列舉了

int mod_sqrt(int x)

void poly_sqrt(int *a, int len)

int len1 = len / 2;

int *f0 = new int[len * 2];

for (int i = 0; i < len1; i++) f0[i] = a[i];

for (int i = len1; i < len * 2; i++) f0[i] = 0;

poly_sqrt(f0, len1);

for (int i = len1; i < len * 2; i++) f0[i] = 0;

int *tmp = new int[len * 2];

for (int i = 0; i < len * 2; i++) tmp[i] = f0[i] * 2 % p;

poly_inv(tmp, len);

ntt(f0, len * 2, 1);

for (int i = 0; i < len * 2; i++) f0[i] = f0[i] * (long long)f0[i] % p;

ntt(f0, len * 2, -1);

for (int i = 0; i < len; i++) f0[i] = (f0[i] + a[i]) % p;

ntt(f0, len * 2, 1);

for (int i = len; i < 2 * len; i++) tmp[i] = 0;

ntt(tmp, len * 2, 1);

for (int i = 0; i < len * 2; i++) a[i] = tmp[i] * (long long)f0[i] % p;

ntt(a, len * 2, -1);

for (int i = len; i < len * 2; i++) a[i] = 0;

delete tmp;

delete f0;

}void poly_exp(int *a, int len)

int len1 = len / 2;

int *f0 = new int[len * 2];

for (int i = 0; i < len1; i++) f0[i] = a[i];

for (int i = len1; i < len * 2; i++) f0[i] = 0;

poly_exp(f0, len1);

for (int i = len1; i < len * 2; i++) f0[i] = 0;

int *lnf0 = new int[len * 2];

for (int i = 0; i < len * 2; i++) lnf0[i] = f0[i];

poly_ln(lnf0, len);

a[0]++;

for (int i = 0; i < len; i++)

ntt(a, len * 2, 1);

ntt(f0, len * 2, 1);

for (int i = 0; i < len * 2; i++) a[i] = a[i] * (long long)f0[i] % p;

ntt(a, len * 2, -1);

for (int i = len; i < len * 2; i++) a[i] = 0;

}void poly_qpow(int *a, int len, int n)

for (int i = 0; i < len * 2; i++) tmp[i] = tmp[i] * (long long)tmp[i] % p;

ntt(tmp, len * 2, -1);

for (int i = len; i < len * 2; i++) tmp[i] = 0;

n >>= 1;

} delete tmp;

}int lagrange_inversion(int *aa, int len, int n)

int a[1000000], n, len = 1;

int main()

多項式板子

板子封裝8太行,湊合著用吧 可能以後會把推導補上吧 咕咕咕 求逆 ll a mn b mn r mn void init int n void inv int f,int g,int n int mid n 1 1 inv f,g,mid int len 1 while len n 2 len 1 ...

模板 多項式乘法(FFT) FFT板子

輸入n,m 1e6 n,m 1e6 n,m 1e 6 輸入n 1 n 1n 1個數字表示從低到高f x f x f x 的係數輸入m 1 m 1m 1個數表示從低到高g x g x g x 的係數輸出 一行n m 1 n m 1 n m 1個數表示f x g x f x g x f x g x 從低...

我的多項式全家桶板子

博主最近心血來潮,貼貼全家桶。本多項式全家桶包含了 多項式乘法,多項式求逆,多項式求ln,多項式求exp,多項式除法,多項式取模,多項式多點求值,以及乙個為了多點求值用的分治ntt。由於時代變了,博主的多點求值使用了常數較小的版本。include define i inline define fi ...