多項式多點求值

2022-05-27 16:27:12 字數 1665 閱讀 2568

給定乙個多項式和m個x,求相應的y

我們把需要求值的點均分成兩個集合s1,s2,構造兩個多項式p1,p2,使得這兩個多項式分別為這兩個集合的零點。則多項式a%p1對於s1滿足a%p1對s1內元素求值和a相同,a%p2對於s2內求值和a相同,而它們次數都是n/2,分治遞迴下去繼續求值即可。

由於多項式取模的陣列版還不會寫,這裡借用的以前的vector版,有非常大的優化空間(vector真香)

#include using namespace std;

const int p = 998244353;

int qpow(int x, int y)

return res;

}void fntt(vector&a, int len, int flag)

} }if (flag == -1)

delete r;

}vectoroperator*(vectora, vectorb)

vectorpoly_inv(vectora)

int n = a.size(), newsz = (n + 1) >> 1;

vectorb(a);

b.resize(newsz);

b = poly_inv(b);

int len = 1;

while (len <= (n << 1)) len <<= 1;

vectorc(a);

fntt(a, len, 1);

fntt(b, len, 1);

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

a[i] = ((1ll * b[i] * (2 - 1ll * a[i] * b[i] % p)) % p + p) % p;

fntt(a, len, -1);

a.resize(n);

return a;

}vectorpoly_r(vectora)

void div(vectorf, vectorg, vector&q, vector&r)

int n, m;

vectorf, tmp[1000010];

int a[100010], res[100010], le[1000010], re[1000010], tot;

vectorprework(int l, int r)

int mid = (l + r) / 2;

le[id] = tot + 1;

vectorres = prework(l, mid);

re[id] = tot + 1;

res = res * prework(mid + 1, r);

return tmp[id] = res;

}void work(int l, int r, vectorsb)

vectorfl = tmp[le[id]], fr = tmp[re[id]];

vectortmp1, rel, rer;

div(sb, fl, tmp1, rel);

div(sb, fr, tmp1, rer);

int mid = (l + r) / 2;

work(l, mid, rel);

work(mid + 1, r, rer);

}int main()

多項式多點求值

給出乙個 n 次多項式 f x 對於 i in 1,m 求 f a i 答案對 998244353 取模 n,m in 1,64000 a i,x i f x in 0,998244353 考慮遞迴求解,令 mid lfloor dfrac m2 rfloor p 0 x prod x a i p ...

更快的多項式多點求值?

乙個奇妙的科技 定義卷積矩陣 m begin a 0 0 0 a 1 a 0 0 a 2 a 1 a 0 end 顯然,我們把多項式係數 a 0,a 1.拿下來放到這個方陣中,另乙個多項式寫成列向量的形式,用此矩陣乘向量即是對另乙個多項式模 x n 意義下的多項式乘法 冪和矩陣 a begin 1 ...

多項式求值

例2 8 多項式求值 考察多項式p x n cix i i 0 如果cn 0,則p 是乙個n 維多項式。下面程式可用來計算對於給定的值x,p x 的實際取值。假定根據f o r迴圈內部所執行的加和乘的次數來估算時間複雜性。可以使用維數n 作為例項特徵。進入f o r迴圈的總次數為n,每次迴圈執行1次...