fork(1) download
  1. /*
  2. Author : DeMen100ns (a.k.a Vo Khac Trieu)
  3. School : VNU-HCM High school for the Gifted
  4. fuck you adhoc
  5. */
  6.  
  7. #include <bits/stdc++.h>
  8. #define endl '\n'
  9.  
  10. using namespace std;
  11.  
  12. // https://g...content-available-to-author-only...b.com/e-maxx-eng/e-maxx-eng-aux/blob/master/src/polynomial.cpp
  13.  
  14. /* Verified on https://j...content-available-to-author-only...o.jp:
  15. - N = 500'000:
  16. -- Convolution, 440ms (https://j...content-available-to-author-only...o.jp/submission/85695)
  17. -- Convolution (mod 1e9+7), 430ms (https://j...content-available-to-author-only...o.jp/submission/85696)
  18. -- Inv of power series, 713ms (https://j...content-available-to-author-only...o.jp/submission/85694)
  19. -- Exp of power series, 2157ms (https://j...content-available-to-author-only...o.jp/submission/85698)
  20. -- Log of power series, 1181ms (https://j...content-available-to-author-only...o.jp/submission/85699)
  21. -- Pow of power series, 3275ms (https://j...content-available-to-author-only...o.jp/submission/85703)
  22. -- Sqrt of power series, 1919ms (https://j...content-available-to-author-only...o.jp/submission/85705)
  23. -- P(x) -> P(x+a), 523ms (https://j...content-available-to-author-only...o.jp/submission/85706)
  24. -- Division of polynomials, 996ms (https://j...content-available-to-author-only...o.jp/submission/85707)
  25. - N = 100'000:
  26. -- Multipoint evaluation, 2161ms (https://j...content-available-to-author-only...o.jp/submission/85709)
  27. -- Polynomial interpolation, 2551ms (https://j...content-available-to-author-only...o.jp/submission/85711)
  28. -- Kth term of Linear Recurrence, 2913ms (https://j...content-available-to-author-only...o.jp/submission/85727)
  29. - N = 50'000:
  30. -- Inv of Polynomials, 1691ms (https://j...content-available-to-author-only...o.jp/submission/85713)
  31. - N = 10'000:
  32. -- Find Linear Recurrence, 346ms (https://j...content-available-to-author-only...o.jp/submission/85025)
  33. /////////
  34. The main goal of this library is to implement common polynomial functionality in a
  35. reasonable from competitive programming POV complexity, while also doing it in as
  36. straight-forward way as possible.
  37. Therefore, primary purpose of the library is educational and most of constant-time
  38. optimizations that may significantly harm the code readability were not used.
  39. The library is reasonably fast and generally can be used in most problems where
  40. polynomial operations constitute intended solution. However, it is recommended to
  41. seek out other implementations when the time limit is tight or you really want to
  42. squeeze a solution when it is probably not the intended one.
  43. */
  44.  
  45. namespace algebra {
  46. const int maxn = 1 << 18;
  47. const int magic = 250; // threshold for sizes to run the naive algo
  48. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  49.  
  50. template<typename T>
  51. T bpow(T x, size_t n) {
  52. if(n == 0) {
  53. return T(1);
  54. } else {
  55. auto t = bpow(x, n / 2);
  56. t = t * t;
  57. return n % 2 ? x * t : t;
  58. }
  59. }
  60.  
  61. template<int m>
  62. struct modular {
  63. // https://e...content-available-to-author-only...a.org/wiki/Berlekamp-Rabin_algorithm
  64. // solves x^2 = y (mod m) assuming m is prime in O(log m).
  65. // returns nullopt if no sol.
  66. optional<modular> sqrt() const {
  67. static modular y;
  68. y = *this;
  69. if(r == 0) {
  70. return 0;
  71. } else if(bpow(y, (m - 1) / 2) != modular(1)) {
  72. return nullopt;
  73. } else {
  74. while(true) {
  75. modular z = rng();
  76. if(z * z == *this) {
  77. return z;
  78. }
  79. struct lin {
  80. modular a, b;
  81. lin(modular a, modular b): a(a), b(b) {}
  82. lin(modular a): a(a), b(0) {}
  83. lin operator * (const lin& t) {
  84. return {
  85. a * t.a + b * t.b * y,
  86. a * t.b + b * t.a
  87. };
  88. }
  89. } x(z, 1); // z + x
  90. x = bpow(x, (m - 1) / 2);
  91. if(x.b != modular(0)) {
  92. return x.b.inv();
  93. }
  94. }
  95. }
  96. }
  97.  
  98. int r;
  99. constexpr modular(): r(0) {}
  100. constexpr modular(int64_t rr): r(rr % m) {if(r < 0) r += m;}
  101. modular inv() const {return bpow(*this, m - 2);}
  102. modular operator - () const {return r ? m - r : 0;}
  103. modular operator * (const modular &t) const {return (int64_t)r * t.r % m;}
  104. modular operator / (const modular &t) const {return *this * t.inv();}
  105. modular operator += (const modular &t) {r += t.r; if(r >= m) r -= m; return *this;}
  106. modular operator -= (const modular &t) {r -= t.r; if(r < 0) r += m; return *this;}
  107. modular operator + (const modular &t) const {return modular(*this) += t;}
  108. modular operator - (const modular &t) const {return modular(*this) -= t;}
  109. modular operator *= (const modular &t) {return *this = *this * t;}
  110. modular operator /= (const modular &t) {return *this = *this / t;}
  111.  
  112. bool operator == (const modular &t) const {return r == t.r;}
  113. bool operator != (const modular &t) const {return r != t.r;}
  114.  
  115. explicit operator int() const {return r;}
  116. int64_t rem() const {return 2 * r > m ? r - m : r;}
  117. };
  118.  
  119. template<int T>
  120. istream& operator >> (istream &in, modular<T> &x) {
  121. return in >> x.r;
  122. }
  123.  
  124. template<int T>
  125. ostream& operator << (ostream &out, modular<T> const& x) {
  126. return out << x.r;
  127. }
  128.  
  129. template<typename T>
  130. T fact(int n) {
  131. static T F[maxn];
  132. static bool init = false;
  133. if(!init) {
  134. F[0] = T(1);
  135. for(int i = 1; i < maxn; i++) {
  136. F[i] = F[i - 1] * T(i);
  137. }
  138. init = true;
  139. }
  140. return F[n];
  141. }
  142.  
  143. template<typename T>
  144. T rfact(int n) {
  145. static T F[maxn];
  146. static bool init = false;
  147. if(!init) {
  148. F[maxn - 1] = T(1) / fact<T>(maxn - 1);
  149. for(int i = maxn - 2; i >= 0; i--) {
  150. F[i] = F[i + 1] * T(i + 1);
  151. }
  152. init = true;
  153. }
  154. return F[n];
  155. }
  156.  
  157. namespace fft {
  158. using ftype = double;
  159. struct point {
  160. ftype x, y;
  161.  
  162. ftype real() {return x;}
  163. ftype imag() {return y;}
  164.  
  165. point(): x(0), y(0){}
  166. point(ftype x, ftype y = 0): x(x), y(y){}
  167.  
  168. static point polar(ftype rho, ftype ang) {
  169. return point{rho * cos(ang), rho * sin(ang)};
  170. }
  171.  
  172. point conj() const {
  173. return {x, -y};
  174. }
  175.  
  176. point operator +=(const point &t) {x += t.x, y += t.y; return *this;}
  177. point operator +(const point &t) const {return point(*this) += t;}
  178. point operator -(const point &t) const {return {x - t.x, y - t.y};}
  179. point operator *(const point &t) const {return {x * t.x - y * t.y, x * t.y + y * t.x};}
  180. };
  181.  
  182. point w[maxn]; // w[2^n + k] = exp(pi * k / (2^n))
  183. int bitr[maxn];// b[2^n + k] = bitreverse(k)
  184. const ftype pi = acos(-1);
  185. bool initiated = 0;
  186. void init() {
  187. if(!initiated) {
  188. for(int i = 1; i < maxn; i *= 2) {
  189. int ti = i / 2;
  190. for(int j = 0; j < i; j++) {
  191. w[i + j] = point::polar(ftype(1), pi * j / i);
  192. if(ti) {
  193. bitr[i + j] = 2 * bitr[ti + j % ti] + (j >= ti);
  194. }
  195. }
  196. }
  197. initiated = 1;
  198. }
  199. }
  200.  
  201. void fft(auto &a, int n) {
  202. init();
  203. if(n == 1) {
  204. return;
  205. }
  206. int hn = n / 2;
  207. for(int i = 0; i < n; i++) {
  208. int ti = 2 * bitr[hn + i % hn] + (i > hn);
  209. if(i < ti) {
  210. swap(a[i], a[ti]);
  211. }
  212. }
  213. for(int i = 1; i < n; i *= 2) {
  214. for(int j = 0; j < n; j += 2 * i) {
  215. for(int k = j; k < j + i; k++) {
  216. point t = a[k + i] * w[i + k - j];
  217. a[k + i] = a[k] - t;
  218. a[k] += t;
  219. }
  220. }
  221. }
  222. }
  223.  
  224. void mul_slow(vector<auto> &a, const vector<auto> &b) {
  225. if(a.empty() || b.empty()) {
  226. a.clear();
  227. } else {
  228. int n = a.size();
  229. int m = b.size();
  230. a.resize(n + m - 1);
  231. for(int k = n + m - 2; k >= 0; k--) {
  232. a[k] *= b[0];
  233. for(int j = max(k - n + 1, 1); j < min(k + 1, m); j++) {
  234. a[k] += a[k - j] * b[j];
  235. }
  236. }
  237. }
  238. }
  239.  
  240. template<int m>
  241. struct dft {
  242. static constexpr int split = 1 << 15;
  243. vector<point> A;
  244.  
  245. dft(vector<modular<m>> const& a, size_t n): A(n) {
  246. for(size_t i = 0; i < min(n, a.size()); i++) {
  247. A[i] = point(
  248. a[i].rem() % split,
  249. a[i].rem() / split
  250. );
  251. }
  252. if(n) {
  253. fft(A, n);
  254. }
  255. }
  256.  
  257. auto operator * (dft const& B) {
  258. assert(A.size() == B.A.size());
  259. size_t n = A.size();
  260. if(!n) {
  261. return vector<modular<m>>();
  262. }
  263. vector<point> C(n), D(n);
  264. for(size_t i = 0; i < n; i++) {
  265. C[i] = A[i] * (B[i] + B[(n - i) % n].conj());
  266. D[i] = A[i] * (B[i] - B[(n - i) % n].conj());
  267. }
  268. fft(C, n);
  269. fft(D, n);
  270. reverse(begin(C) + 1, end(C));
  271. reverse(begin(D) + 1, end(D));
  272. int t = 2 * n;
  273. vector<modular<m>> res(n);
  274. for(size_t i = 0; i < n; i++) {
  275. modular<m> A0 = llround(C[i].real() / t);
  276. modular<m> A1 = llround(C[i].imag() / t + D[i].imag() / t);
  277. modular<m> A2 = llround(D[i].real() / t);
  278. res[i] = A0 + A1 * split - A2 * split * split;
  279. }
  280. return res;
  281. }
  282.  
  283. point& operator [](int i) {return A[i];}
  284. point operator [](int i) const {return A[i];}
  285. };
  286.  
  287. size_t com_size(size_t as, size_t bs) {
  288. if(!as || !bs) {
  289. return 0;
  290. }
  291. size_t n = as + bs - 1;
  292. while(__builtin_popcount(n) != 1) {
  293. n++;
  294. }
  295. return n;
  296. }
  297.  
  298. template<int m>
  299. void mul(vector<modular<m>> &a, vector<modular<m>> b) {
  300. if(min(a.size(), b.size()) < magic) {
  301. mul_slow(a, b);
  302. return;
  303. }
  304. auto n = com_size(a.size(), b.size());
  305. auto A = dft<m>(a, n);
  306. if(a == b) {
  307. a = A * A;
  308. } else {
  309. a = A * dft<m>(b, n);
  310. }
  311. }
  312. }
  313.  
  314. template<typename T>
  315. struct poly {
  316. vector<T> a;
  317.  
  318. void normalize() { // get rid of leading zeroes
  319. while(!a.empty() && a.back() == T(0)) {
  320. a.pop_back();
  321. }
  322. }
  323.  
  324. poly(){}
  325. poly(T a0) : a{a0}{normalize();}
  326. poly(const vector<T> &t) : a(t){normalize();}
  327.  
  328. poly operator -() const {
  329. auto t = *this;
  330. for(auto &it: t.a) {
  331. it = -it;
  332. }
  333. return t;
  334. }
  335.  
  336. poly operator += (const poly &t) {
  337. a.resize(max(a.size(), t.a.size()));
  338. for(size_t i = 0; i < t.a.size(); i++) {
  339. a[i] += t.a[i];
  340. }
  341. normalize();
  342. return *this;
  343. }
  344.  
  345. poly operator -= (const poly &t) {
  346. a.resize(max(a.size(), t.a.size()));
  347. for(size_t i = 0; i < t.a.size(); i++) {
  348. a[i] -= t.a[i];
  349. }
  350. normalize();
  351. return *this;
  352. }
  353. poly operator + (const poly &t) const {return poly(*this) += t;}
  354. poly operator - (const poly &t) const {return poly(*this) -= t;}
  355.  
  356. poly mod_xk(size_t k) const { // get first k coefficients
  357. return vector<T>(begin(a), begin(a) + min(k, a.size()));
  358. }
  359.  
  360. poly mul_xk(size_t k) const { // multiply by x^k
  361. auto res = a;
  362. res.insert(begin(res), k, 0);
  363. return res;
  364. }
  365.  
  366. poly div_xk(size_t k) const { // drop first k coefficients
  367. return vector<T>(begin(a) + min(k, a.size()), end(a));
  368. }
  369.  
  370. poly substr(size_t l, size_t r) const { // return mod_xk(r).div_xk(l)
  371. return vector<T>(
  372. begin(a) + min(l, a.size()),
  373. begin(a) + min(r, a.size())
  374. );
  375. }
  376.  
  377. poly operator *= (const poly &t) {fft::mul(a, t.a); normalize(); return *this;}
  378. poly operator * (const poly &t) const {return poly(*this) *= t;}
  379.  
  380. poly reverse(size_t n) const { // computes x^n A(x^{-1})
  381. auto res = a;
  382. res.resize(max(n, res.size()));
  383. return vector<T>(res.rbegin(), res.rbegin() + n);
  384. }
  385.  
  386. poly reverse() const {
  387. return reverse(deg() + 1);
  388. }
  389.  
  390. pair<poly, poly> divmod_slow(const poly &b) const { // when divisor or quotient is small
  391. vector<T> A(a);
  392. vector<T> res;
  393. while(A.size() >= b.a.size()) {
  394. res.push_back(A.back() / b.a.back());
  395. if(res.back() != T(0)) {
  396. for(size_t i = 0; i < b.a.size(); i++) {
  397. A[A.size() - i - 1] -= res.back() * b.a[b.a.size() - i - 1];
  398. }
  399. }
  400. A.pop_back();
  401. }
  402. std::reverse(begin(res), end(res));
  403. return {res, A};
  404. }
  405.  
  406. pair<poly, poly> divmod_hint(poly const& b, poly const& binv) const { // when inverse is known
  407. assert(!b.is_zero());
  408. if(deg() < b.deg()) {
  409. return {poly{0}, *this};
  410. }
  411. int d = deg() - b.deg();
  412. if(min(d, b.deg()) < magic) {
  413. return divmod_slow(b);
  414. }
  415. poly D = (reverse().mod_xk(d + 1) * binv.mod_xk(d + 1)).mod_xk(d + 1).reverse(d + 1);
  416. return {D, *this - D * b};
  417. }
  418.  
  419. pair<poly, poly> divmod(const poly &b) const { // returns quotiend and remainder of a mod b
  420. assert(!b.is_zero());
  421. if(deg() < b.deg()) {
  422. return {poly{0}, *this};
  423. }
  424. int d = deg() - b.deg();
  425. if(min(d, b.deg()) < magic) {
  426. return divmod_slow(b);
  427. }
  428. poly D = (reverse().mod_xk(d + 1) * b.reverse().inv(d + 1)).mod_xk(d + 1).reverse(d + 1);
  429. return {D, *this - D * b};
  430. }
  431.  
  432. // (ax+b) / (cx+d)
  433. struct transform {
  434. poly a, b, c, d;
  435. transform(poly a, poly b = T(1), poly c = T(1), poly d = T(0)): a(a), b(b), c(c), d(d){}
  436.  
  437. transform operator *(transform const& t) {
  438. return {
  439. a*t.a + b*t.c, a*t.b + b*t.d,
  440. c*t.a + d*t.c, c*t.b + d*t.d
  441. };
  442. }
  443.  
  444. transform adj() {
  445. return transform(d, -b, -c, a);
  446. }
  447.  
  448. auto apply(poly A, poly B) {
  449. return make_pair(a * A + b * B, c * A + d * B);
  450. }
  451. };
  452.  
  453. template<typename Q>
  454. static void concat(vector<Q> &a, vector<Q> const& b) {
  455. for(auto it: b) {
  456. a.push_back(it);
  457. }
  458. }
  459.  
  460. // finds a transform that changes A/B to A'/B' such that
  461. // deg B' is at least 2 times less than deg A
  462. static pair<vector<poly>, transform> half_gcd(poly A, poly B) {
  463. assert(A.deg() >= B.deg());
  464. int m = (A.deg() + 1) / 2;
  465. if(B.deg() < m) {
  466. return {{}, {T(1), T(0), T(0), T(1)}};
  467. }
  468. auto [ar, Tr] = half_gcd(A.div_xk(m), B.div_xk(m));
  469. tie(A, B) = Tr.adj().apply(A, B);
  470. if(B.deg() < m) {
  471. return {ar, Tr};
  472. }
  473. auto [ai, R] = A.divmod(B);
  474. tie(A, B) = make_pair(B, R);
  475. int k = 2 * m - B.deg();
  476. auto [as, Ts] = half_gcd(A.div_xk(k), B.div_xk(k));
  477. concat(ar, {ai});
  478. concat(ar, as);
  479. return {ar, Tr * transform(ai) * Ts};
  480. }
  481.  
  482. // return a transform that reduces A / B to gcd(A, B) / 0
  483. static pair<vector<poly>, transform> full_gcd(poly A, poly B) {
  484. vector<poly> ak;
  485. vector<transform> trs;
  486. while(!B.is_zero()) {
  487. if(2 * B.deg() > A.deg()) {
  488. auto [a, Tr] = half_gcd(A, B);
  489. concat(ak, a);
  490. trs.push_back(Tr);
  491. tie(A, B) = trs.back().adj().apply(A, B);
  492. } else {
  493. auto [a, R] = A.divmod(B);
  494. ak.push_back(a);
  495. trs.emplace_back(a);
  496. tie(A, B) = make_pair(B, R);
  497. }
  498. }
  499. trs.emplace_back(T(1), T(0), T(0), T(1));
  500. while(trs.size() >= 2) {
  501. trs[trs.size() - 2] = trs[trs.size() - 2] * trs[trs.size() - 1];
  502. trs.pop_back();
  503. }
  504. return {ak, trs.back()};
  505. }
  506.  
  507. static poly gcd(poly A, poly B) {
  508. if(A.deg() < B.deg()) {
  509. return full_gcd(B, A);
  510. }
  511. auto Tr = fraction(A, B);
  512. return Tr.d * A - Tr.b * B;
  513. }
  514.  
  515. // Returns the characteristic polynomial
  516. // of the minimum linear recurrence for the sequence
  517. poly min_rec_slow(int d) const {
  518. auto R1 = mod_xk(d + 1).reverse(d + 1), R2 = xk(d + 1);
  519. auto Q1 = poly(T(1)), Q2 = poly(T(0));
  520. while(!R2.is_zero()) {
  521. auto [a, nR] = R1.divmod(R2); // R1 = a*R2 + nR, deg nR < deg R2
  522. tie(R1, R2) = make_tuple(R2, nR);
  523. tie(Q1, Q2) = make_tuple(Q2, Q1 + a * Q2);
  524. if(R2.deg() < Q2.deg()) {
  525. return Q2 / Q2.lead();
  526. }
  527. }
  528. assert(0);
  529. }
  530.  
  531. static transform convergent(auto L, auto R) { // computes product on [L, R)
  532. if(R - L == 1) {
  533. return transform(*L);
  534. } else {
  535. int s = 0;
  536. for(int i = 0; i < R - L; i++) {
  537. s += L[i].a.size();
  538. }
  539. int c = 0;
  540. for(int i = 0; i < R - L; i++) {
  541. c += L[i].a.size();
  542. if(2 * c > s) {
  543. return convergent(L, L + i) * convergent(L + i, R);
  544. }
  545. }
  546. assert(0);
  547. }
  548. }
  549.  
  550. poly min_rec(int d) const {
  551. if(d < magic) {
  552. return min_rec_slow(d);
  553. }
  554. auto R2 = mod_xk(d + 1).reverse(d + 1), R1 = xk(d + 1);
  555. if(R2.is_zero()) {
  556. return poly(1);
  557. }
  558. auto [a, Tr] = full_gcd(R1, R2);
  559. int dr = (d + 1) - a[0].deg();
  560. int dp = 0;
  561. for(size_t i = 0; i + 1 < a.size(); i++) {
  562. dr -= a[i + 1].deg();
  563. dp += a[i].deg();
  564. if(dr < dp) {
  565. auto ans = convergent(begin(a), begin(a) + i + 1);
  566. return ans.a / ans.a.lead();
  567. }
  568. }
  569. auto ans = convergent(begin(a), end(a));
  570. return ans.a / ans.a.lead();
  571. }
  572.  
  573. // calculate inv to *this modulo t
  574. // quadratic complexity
  575. optional<poly> inv_mod_slow(poly const& t) const {
  576. auto R1 = *this, R2 = t;
  577. auto Q1 = poly(T(1)), Q2 = poly(T(0));
  578. int k = 0;
  579. while(!R2.is_zero()) {
  580. k ^= 1;
  581. auto [a, nR] = R1.divmod(R2);
  582. tie(R1, R2) = make_tuple(R2, nR);
  583. tie(Q1, Q2) = make_tuple(Q2, Q1 + a * Q2);
  584. }
  585. if(R1.deg() > 0) {
  586. return nullopt;
  587. } else {
  588. return (k ? -Q1 : Q1) / R1[0];
  589. }
  590. }
  591.  
  592. optional<poly> inv_mod(poly const &t) const {
  593. assert(!t.is_zero());
  594. if(false && min(deg(), t.deg()) < magic) {
  595. return inv_mod_slow(t);
  596. }
  597. auto A = t, B = *this % t;
  598. auto [a, Tr] = full_gcd(A, B);
  599. auto g = Tr.d * A - Tr.b * B;
  600. if(g.deg() != 0) {
  601. return nullopt;
  602. }
  603. return -Tr.b / g[0];
  604. };
  605.  
  606. poly operator / (const poly &t) const {return divmod(t).first;}
  607. poly operator % (const poly &t) const {return divmod(t).second;}
  608. poly operator /= (const poly &t) {return *this = divmod(t).first;}
  609. poly operator %= (const poly &t) {return *this = divmod(t).second;}
  610. poly operator *= (const T &x) {
  611. for(auto &it: a) {
  612. it *= x;
  613. }
  614. normalize();
  615. return *this;
  616. }
  617. poly operator /= (const T &x) {
  618. for(auto &it: a) {
  619. it /= x;
  620. }
  621. normalize();
  622. return *this;
  623. }
  624. poly operator * (const T &x) const {return poly(*this) *= x;}
  625. poly operator / (const T &x) const {return poly(*this) /= x;}
  626.  
  627. poly conj() const { // A(x) -> A(-x)
  628. auto res = *this;
  629. for(int i = 1; i <= deg(); i += 2) {
  630. res[i] = -res[i];
  631. }
  632. return res;
  633. }
  634.  
  635. void print(int n) const {
  636. for(int i = 0; i < n; i++) {
  637. cout << (*this)[i] << ' ';
  638. }
  639. cout << "\n";
  640. }
  641.  
  642. void print() const {
  643. print(deg() + 1);
  644. }
  645.  
  646. T eval(T x) const { // evaluates in single point x
  647. T res(0);
  648. for(int i = deg(); i >= 0; i--) {
  649. res *= x;
  650. res += a[i];
  651. }
  652. return res;
  653. }
  654.  
  655. T lead() const { // leading coefficient
  656. assert(!is_zero());
  657. return a.back();
  658. }
  659.  
  660. int deg() const { // degree, -1 for P(x) = 0
  661. return (int)a.size() - 1;
  662. }
  663.  
  664. bool is_zero() const {
  665. return a.empty();
  666. }
  667.  
  668. T operator [](int idx) const {
  669. return idx < 0 || idx > deg() ? T(0) : a[idx];
  670. }
  671.  
  672. T& coef(size_t idx) { // mutable reference at coefficient
  673. return a[idx];
  674. }
  675.  
  676. bool operator == (const poly &t) const {return a == t.a;}
  677. bool operator != (const poly &t) const {return a != t.a;}
  678.  
  679. poly deriv(int k = 1) { // calculate derivative
  680. if(deg() + 1 < k) {
  681. return poly(T(0));
  682. }
  683. vector<T> res(deg() + 1 - k);
  684. for(int i = k; i <= deg(); i++) {
  685. res[i - k] = fact<T>(i) * rfact<T>(i - k) * a[i];
  686. }
  687. return res;
  688. }
  689.  
  690. poly integr() { // calculate integral with C = 0
  691. vector<T> res(deg() + 2);
  692. for(int i = 0; i <= deg(); i++) {
  693. res[i + 1] = a[i] / T(i + 1);
  694. }
  695. return res;
  696. }
  697.  
  698. size_t trailing_xk() const { // Let p(x) = x^k * t(x), return k
  699. if(is_zero()) {
  700. return -1;
  701. }
  702. int res = 0;
  703. while(a[res] == T(0)) {
  704. res++;
  705. }
  706. return res;
  707. }
  708.  
  709. poly log(size_t n) { // calculate log p(x) mod x^n
  710. assert(a[0] == T(1));
  711. return (deriv().mod_xk(n) * inv(n)).integr().mod_xk(n);
  712. }
  713.  
  714. poly exp(size_t n) { // calculate exp p(x) mod x^n
  715. if(is_zero()) {
  716. return T(1);
  717. }
  718. assert(a[0] == T(0));
  719. poly ans = T(1);
  720. size_t a = 1;
  721. while(a < n) {
  722. poly C = ans.log(2 * a).div_xk(a) - substr(a, 2 * a);
  723. ans -= (ans * C).mod_xk(a).mul_xk(a);
  724. a *= 2;
  725. }
  726. return ans.mod_xk(n);
  727. }
  728.  
  729. poly pow_bin(int64_t k, size_t n) { // O(n log n log k)
  730. if(k == 0) {
  731. return poly(1).mod_xk(n);
  732. } else {
  733. auto t = pow(k / 2, n);
  734. t *= t;
  735. return (k % 2 ? *this * t : t).mod_xk(n);
  736. }
  737. }
  738.  
  739. // Do not compute inverse from scratch
  740. poly powmod_hint(int64_t k, poly const& md, poly const& mdinv) {
  741. if(k == 0) {
  742. return poly(1);
  743. } else {
  744. auto t = powmod_hint(k / 2, md, mdinv);
  745. t = (t * t).divmod_hint(md, mdinv).second;
  746. if(k % 2) {
  747. t = (t * *this).divmod_hint(md, mdinv).second;
  748. }
  749. return t;
  750. }
  751. }
  752.  
  753. poly powmod(int64_t k, poly const& md) {
  754. auto mdinv = md.reverse().inv(md.deg() + 1);
  755. return powmod_hint(k, md, mdinv);
  756. }
  757.  
  758. // O(d * n) with the derivative trick from
  759. // https://c...content-available-to-author-only...s.com/blog/entry/73947?#comment-581173
  760. poly pow_dn(int64_t k, size_t n) {
  761. if(n == 0) {
  762. return poly(T(0));
  763. }
  764. assert((*this)[0] != T(0));
  765. vector<T> Q(n);
  766. Q[0] = bpow(a[0], k);
  767. for(int i = 1; i < (int)n; i++) {
  768. for(int j = 1; j <= min(deg(), i); j++) {
  769. Q[i] += a[j] * Q[i - j] * (T(k) * T(j) - T(i - j));
  770. }
  771. Q[i] /= T(i) * a[0];
  772. }
  773. return Q;
  774. }
  775.  
  776. // calculate p^k(n) mod x^n in O(n log n)
  777. // might be quite slow due to high constant
  778. poly pow(int64_t k, size_t n) {
  779. if(is_zero()) {
  780. return k ? *this : poly(1);
  781. }
  782. int i = trailing_xk();
  783. if(i > 0) {
  784. return k >= int64_t(n + i - 1) / i ? poly(T(0)) : div_xk(i).pow(k, n - i * k).mul_xk(i * k);
  785. }
  786. if(min(deg(), (int)n) <= magic) {
  787. return pow_dn(k, n);
  788. }
  789. if(k <= magic) {
  790. return pow_bin(k, n);
  791. }
  792. T j = a[i];
  793. poly t = *this / j;
  794. return bpow(j, k) * (t.log(n) * T(k)).exp(n).mod_xk(n);
  795. }
  796.  
  797. // returns nullopt if undefined
  798. optional<poly> sqrt(size_t n) const {
  799. if(is_zero()) {
  800. return *this;
  801. }
  802. int i = trailing_xk();
  803. if(i % 2) {
  804. return nullopt;
  805. } else if(i > 0) {
  806. auto ans = div_xk(i).sqrt(n - i / 2);
  807. return ans ? ans->mul_xk(i / 2) : ans;
  808. }
  809. optional<T> st = T(1);
  810. if(st) {
  811. poly ans = *st;
  812. size_t a = 1;
  813. while(a < n) {
  814. a *= 2;
  815. ans -= (ans - mod_xk(a) * ans.inv(a)).mod_xk(a) / 2;
  816. }
  817. return ans.mod_xk(n);
  818. }
  819. return nullopt;
  820. }
  821.  
  822. poly mulx(T a) const { // component-wise multiplication with a^k
  823. T cur = 1;
  824. poly res(*this);
  825. for(int i = 0; i <= deg(); i++) {
  826. res.coef(i) *= cur;
  827. cur *= a;
  828. }
  829. return res;
  830. }
  831.  
  832. poly mulx_sq(T a) const { // component-wise multiplication with a^{k^2}
  833. T cur = a;
  834. T total = 1;
  835. T aa = a * a;
  836. poly res(*this);
  837. for(int i = 0; i <= deg(); i++) {
  838. res.coef(i) *= total;
  839. total *= cur;
  840. cur *= aa;
  841. }
  842. return res;
  843. }
  844.  
  845. vector<T> chirpz_even(T z, int n) const { // P(1), P(z^2), P(z^4), ..., P(z^2(n-1))
  846. int m = deg();
  847. if(is_zero()) {
  848. return vector<T>(n, 0);
  849. }
  850. vector<T> vv(m + n);
  851. T zi = T(1) / z;
  852. T zz = zi * zi;
  853. T cur = zi;
  854. T total = 1;
  855. for(int i = 0; i <= max(n - 1, m); i++) {
  856. if(i <= m) {vv[m - i] = total;}
  857. if(i < n) {vv[m + i] = total;}
  858. total *= cur;
  859. cur *= zz;
  860. }
  861. poly w = (mulx_sq(z) * vv).substr(m, m + n).mulx_sq(z);
  862. vector<T> res(n);
  863. for(int i = 0; i < n; i++) {
  864. res[i] = w[i];
  865. }
  866. return res;
  867. }
  868.  
  869. vector<T> chirpz(T z, int n) const { // P(1), P(z), P(z^2), ..., P(z^(n-1))
  870. auto even = chirpz_even(z, (n + 1) / 2);
  871. auto odd = mulx(z).chirpz_even(z, n / 2);
  872. vector<T> ans(n);
  873. for(int i = 0; i < n / 2; i++) {
  874. ans[2 * i] = even[i];
  875. ans[2 * i + 1] = odd[i];
  876. }
  877. if(n % 2 == 1) {
  878. ans[n - 1] = even.back();
  879. }
  880. return ans;
  881. }
  882.  
  883. vector<T> eval(vector<poly> &tree, int v, auto l, auto r) { // auxiliary evaluation function
  884. if(r - l == 1) {
  885. return {eval(*l)};
  886. } else {
  887. auto m = l + (r - l) / 2;
  888. auto A = (*this % tree[2 * v]).eval(tree, 2 * v, l, m);
  889. auto B = (*this % tree[2 * v + 1]).eval(tree, 2 * v + 1, m, r);
  890. A.insert(end(A), begin(B), end(B));
  891. return A;
  892. }
  893. }
  894.  
  895. vector<T> eval(vector<T> x) { // evaluate polynomial in (x1, ..., xn)
  896. int n = x.size();
  897. if(is_zero()) {
  898. return vector<T>(n, T(0));
  899. }
  900. vector<poly> tree(4 * n);
  901. build(tree, 1, begin(x), end(x));
  902. return eval(tree, 1, begin(x), end(x));
  903. }
  904.  
  905. poly inter(vector<poly> &tree, int v, auto l, auto r, auto ly, auto ry) { // auxiliary interpolation function
  906. if(r - l == 1) {
  907. return {*ly / a[0]};
  908. } else {
  909. auto m = l + (r - l) / 2;
  910. auto my = ly + (ry - ly) / 2;
  911. auto A = (*this % tree[2 * v]).inter(tree, 2 * v, l, m, ly, my);
  912. auto B = (*this % tree[2 * v + 1]).inter(tree, 2 * v + 1, m, r, my, ry);
  913. return A * tree[2 * v + 1] + B * tree[2 * v];
  914. }
  915. }
  916.  
  917. static auto resultant(poly a, poly b) { // computes resultant of a and b
  918. if(b.is_zero()) {
  919. return 0;
  920. } else if(b.deg() == 0) {
  921. return bpow(b.lead(), a.deg());
  922. } else {
  923. int pw = a.deg();
  924. a %= b;
  925. pw -= a.deg();
  926. auto mul = bpow(b.lead(), pw) * T((b.deg() & a.deg() & 1) ? -1 : 1);
  927. auto ans = resultant(b, a);
  928. return ans * mul;
  929. }
  930. }
  931.  
  932. static poly build(vector<poly> &res, int v, auto L, auto R) { // builds evaluation tree for (x-a1)(x-a2)...(x-an)
  933. if(R - L == 1) {
  934. return res[v] = vector<T>{-*L, 1};
  935. } else {
  936. auto M = L + (R - L) / 2;
  937. return res[v] = build(res, 2 * v, L, M) * build(res, 2 * v + 1, M, R);
  938. }
  939. }
  940.  
  941. static auto inter(vector<T> x, vector<T> y) { // interpolates minimum polynomial from (xi, yi) pairs
  942. int n = x.size();
  943. vector<poly> tree(4 * n);
  944. return build(tree, 1, begin(x), end(x)).deriv().inter(tree, 1, begin(x), end(x), begin(y), end(y));
  945. }
  946.  
  947.  
  948. static poly xk(size_t n) { // P(x) = x^n
  949. return poly(T(1)).mul_xk(n);
  950. }
  951.  
  952. static poly ones(size_t n) { // P(x) = 1 + x + ... + x^{n-1}
  953. return vector<T>(n, 1);
  954. }
  955.  
  956. static poly expx(size_t n) { // P(x) = e^x (mod x^n)
  957. return ones(n).borel();
  958. }
  959.  
  960. // [x^k] (a corr b) = sum_{i+j=k} ai*b{m-j}
  961. // = sum_{i-j=k-m} ai*bj
  962. static poly corr(poly a, poly b) { // cross-correlation
  963. return a * b.reverse();
  964. }
  965.  
  966. poly invborel() const { // ak *= k!
  967. auto res = *this;
  968. for(int i = 0; i <= deg(); i++) {
  969. res.coef(i) *= fact<T>(i);
  970. }
  971. return res;
  972. }
  973.  
  974. poly borel() const { // ak /= k!
  975. auto res = *this;
  976. for(int i = 0; i <= deg(); i++) {
  977. res.coef(i) *= rfact<T>(i);
  978. }
  979. return res;
  980. }
  981.  
  982. poly shift(T a) const { // P(x + a)
  983. return (expx(deg() + 1).mulx(a).reverse() * invborel()).div_xk(deg()).borel();
  984. }
  985.  
  986. poly x2() { // P(x) -> P(x^2)
  987. vector<T> res(2 * a.size());
  988. for(size_t i = 0; i < a.size(); i++) {
  989. res[2 * i] = a[i];
  990. }
  991. return res;
  992. }
  993.  
  994. // Return {P0, P1}, where P(x) = P0(x) + xP1(x)
  995. pair<poly, poly> bisect() const {
  996. vector<T> res[2];
  997. res[0].reserve(deg() / 2 + 1);
  998. res[1].reserve(deg() / 2 + 1);
  999. for(int i = 0; i <= deg(); i++) {
  1000. res[i % 2].push_back(a[i]);
  1001. }
  1002. return {res[0], res[1]};
  1003. }
  1004.  
  1005. // Find [x^k] P / Q
  1006. static T kth_rec(poly P, poly Q, int64_t k) {
  1007. while(k > Q.deg()) {
  1008. int n = Q.a.size();
  1009. auto [Q0, Q1] = Q.mulx(-1).bisect();
  1010. auto [P0, P1] = P.bisect();
  1011.  
  1012. int N = fft::com_size((n + 1) / 2, (n + 1) / 2);
  1013.  
  1014. auto Q0f = fft::dft(Q0.a, N);
  1015. auto Q1f = fft::dft(Q1.a, N);
  1016. auto P0f = fft::dft(P0.a, N);
  1017. auto P1f = fft::dft(P1.a, N);
  1018.  
  1019. if(k % 2) {
  1020. P = poly(Q0f * P1f) + poly(Q1f * P0f);
  1021. } else {
  1022. P = poly(Q0f * P0f) + poly(Q1f * P1f).mul_xk(1);
  1023. }
  1024. Q = poly(Q0f * Q0f) - poly(Q1f * Q1f).mul_xk(1);
  1025. k /= 2;
  1026. }
  1027. return (P * Q.inv(Q.deg() + 1))[k];
  1028. }
  1029.  
  1030. poly inv(int n) const { // get inverse series mod x^n
  1031. auto Q = mod_xk(n);
  1032. if(n == 1) {
  1033. return Q[0].inv();
  1034. }
  1035. // Q(-x) = P0(x^2) + xP1(x^2)
  1036. auto [P0, P1] = Q.mulx(-1).bisect();
  1037.  
  1038. int N = fft::com_size((n + 1) / 2, (n + 1) / 2);
  1039.  
  1040. auto P0f = fft::dft(P0.a, N);
  1041. auto P1f = fft::dft(P1.a, N);
  1042.  
  1043. auto TTf = fft::dft(( // Q(x)*Q(-x) = Q0(x^2)^2 - x^2 Q1(x^2)^2
  1044. poly(P0f * P0f) - poly(P1f * P1f).mul_xk(1)
  1045. ).inv((n + 1) / 2).a, N);
  1046.  
  1047. return (
  1048. poly(P0f * TTf).x2() + poly(P1f * TTf).x2().mul_xk(1)
  1049. ).mod_xk(n);
  1050. }
  1051.  
  1052. // compute A(B(x)) mod x^n in O(n^2)
  1053. static poly compose(poly A, poly B, int n) {
  1054. int q = std::sqrt(n);
  1055. vector<poly> Bk(q);
  1056. auto Bq = B.pow(q, n);
  1057. Bk[0] = poly(T(1));
  1058. for(int i = 1; i < q; i++) {
  1059. Bk[i] = (Bk[i - 1] * B).mod_xk(n);
  1060. }
  1061. poly Bqk(1);
  1062. poly ans;
  1063. for(int i = 0; i <= n / q; i++) {
  1064. poly cur;
  1065. for(int j = 0; j < q; j++) {
  1066. cur += Bk[j] * A[i * q + j];
  1067. }
  1068. ans += (Bqk * cur).mod_xk(n);
  1069. Bqk = (Bqk * Bq).mod_xk(n);
  1070. }
  1071. return ans;
  1072. }
  1073.  
  1074. // compute A(B(x)) mod x^n in O(sqrt(pqn log^3 n))
  1075. // preferrable when p = deg A and q = deg B
  1076. // are much less than n
  1077. static poly compose_large(poly A, poly B, int n) {
  1078. if(B[0] != T(0)) {
  1079. return compose_large(A.shift(B[0]), B - B[0], n);
  1080. }
  1081.  
  1082. int q = std::sqrt(n);
  1083. auto [B0, B1] = make_pair(B.mod_xk(q), B.div_xk(q));
  1084.  
  1085. B0 = B0.div_xk(1);
  1086. vector<poly> pw(A.deg() + 1);
  1087. auto getpow = [&](int k) {
  1088. return pw[k].is_zero() ? pw[k] = B0.pow(k, n - k) : pw[k];
  1089. };
  1090.  
  1091. function<poly(poly const&, int, int)> compose_dac = [&getpow, &compose_dac](poly const& f, int m, int N) {
  1092. if(f.deg() <= 0) {
  1093. return f;
  1094. }
  1095. int k = m / 2;
  1096. auto [f0, f1] = make_pair(f.mod_xk(k), f.div_xk(k));
  1097. auto [A, B] = make_pair(compose_dac(f0, k, N), compose_dac(f1, m - k, N - k));
  1098. return (A + (B.mod_xk(N - k) * getpow(k).mod_xk(N - k)).mul_xk(k)).mod_xk(N);
  1099. };
  1100.  
  1101. int r = n / q;
  1102. auto Ar = A.deriv(r);
  1103. auto AB0 = compose_dac(Ar, Ar.deg() + 1, n);
  1104.  
  1105. auto Bd = B0.mul_xk(1).deriv();
  1106.  
  1107. poly ans = T(0);
  1108.  
  1109. vector<poly> B1p(r + 1);
  1110. B1p[0] = poly(T(1));
  1111. for(int i = 1; i <= r; i++) {
  1112. B1p[i] = (B1p[i - 1] * B1.mod_xk(n - i * q)).mod_xk(n - i * q);
  1113. }
  1114. while(r >= 0) {
  1115. ans += (AB0.mod_xk(n - r * q) * rfact<T>(r) * B1p[r]).mul_xk(r * q).mod_xk(n);
  1116. r--;
  1117. if(r >= 0) {
  1118. AB0 = ((AB0 * Bd).integr() + A[r] * fact<T>(r)).mod_xk(n);
  1119. }
  1120. }
  1121.  
  1122. return ans;
  1123. }
  1124. };
  1125.  
  1126. static auto operator * (const auto& a, const poly<auto>& b) {
  1127. return b * a;
  1128. }
  1129. };
  1130.  
  1131. using namespace algebra;
  1132.  
  1133. const int mod = 1e9 + 7;
  1134. const int N = 1e5 + 5;
  1135. const long long INF = 1e18 + 7;
  1136. const int MAXA = 1e9;
  1137. const int B = sqrt(N) + 5;
  1138. typedef modular<mod> base;
  1139. typedef poly<base> polyn;
  1140.  
  1141. int a[N], ct[N];
  1142.  
  1143. void solve()
  1144. {
  1145. int n, k; cin >> n >> k;
  1146.  
  1147. for(int i = 1; i <= n; ++i){
  1148. cin >> a[i];
  1149. ct[a[i]]++;
  1150. }
  1151.  
  1152. vector <base> ans(k + 1, 0);
  1153. for(int i = 1; i <= k; ++i){
  1154. for(int j = 1; j * i <= k; ++j){
  1155. if (j & 1){
  1156. ans[i * j] += (base)ct[i] / j;
  1157. } else {
  1158. ans[i * j] -= (base)ct[i] / j;
  1159. }
  1160. }
  1161. }
  1162.  
  1163. polyn pans = polyn(ans).exp(k + 1);
  1164. cout << pans[k];
  1165. }
  1166.  
  1167. signed main()
  1168. {
  1169. ios_base::sync_with_stdio(0);
  1170. cin.tie(0);
  1171. cout.tie(0);
  1172.  
  1173. freopen("TRE.inp","r",stdin);
  1174. freopen("TRE.out","w",stdout);
  1175.  
  1176. int t = 1; // cin >> t;
  1177. while (t--)
  1178. {
  1179. solve();
  1180. }
  1181. }
  1182.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:66:9: error: ‘optional’ does not name a type; did you mean ‘psignal’?
         optional<modular> sqrt() const {
         ^~~~~~~~
         psignal
prog.cpp:201:18: warning: use of ‘auto’ in parameter declaration only available with -fconcepts
         void fft(auto &a, int n) {
                  ^~~~
prog.cpp:224:30: warning: use of ‘auto’ in parameter declaration only available with -fconcepts
         void mul_slow(vector<auto> &a, const vector<auto> &b) {
                              ^~~~
prog.cpp:224:53: warning: use of ‘auto’ in parameter declaration only available with -fconcepts
         void mul_slow(vector<auto> &a, const vector<auto> &b) {
                                                     ^~~~
prog.cpp:531:37: warning: use of ‘auto’ in parameter declaration only available with -fconcepts
         static transform convergent(auto L, auto R) { // computes product on [L, R)
                                     ^~~~
prog.cpp:531:45: warning: use of ‘auto’ in parameter declaration only available with -fconcepts
         static transform convergent(auto L, auto R) { // computes product on [L, R)
                                             ^~~~
prog.cpp:575:9: error: ‘optional’ does not name a type; did you mean ‘psignal’?
         optional<poly> inv_mod_slow(poly const& t) const {
         ^~~~~~~~
         psignal
prog.cpp:592:9: error: ‘optional’ does not name a type; did you mean ‘psignal’?
         optional<poly> inv_mod(poly const &t) const {
         ^~~~~~~~
         psignal
prog.cpp:798:9: error: ‘optional’ does not name a type; did you mean ‘psignal’?
         optional<poly> sqrt(size_t n) const {
         ^~~~~~~~
         psignal
prog.cpp:883:51: warning: use of ‘auto’ in parameter declaration only available with -fconcepts
         vector<T> eval(vector<poly> &tree, int v, auto l, auto r) { // auxiliary evaluation function
                                                   ^~~~
prog.cpp:883:59: warning: use of ‘auto’ in parameter declaration only available with -fconcepts
         vector<T> eval(vector<poly> &tree, int v, auto l, auto r) { // auxiliary evaluation function
                                                           ^~~~
prog.cpp:905:47: warning: use of ‘auto’ in parameter declaration only available with -fconcepts
         poly inter(vector<poly> &tree, int v, auto l, auto r, auto ly, auto ry) { // auxiliary interpolation function
                                               ^~~~
prog.cpp:905:55: warning: use of ‘auto’ in parameter declaration only available with -fconcepts
         poly inter(vector<poly> &tree, int v, auto l, auto r, auto ly, auto ry) { // auxiliary interpolation function
                                                       ^~~~
prog.cpp:905:63: warning: use of ‘auto’ in parameter declaration only available with -fconcepts
         poly inter(vector<poly> &tree, int v, auto l, auto r, auto ly, auto ry) { // auxiliary interpolation function
                                                               ^~~~
prog.cpp:905:72: warning: use of ‘auto’ in parameter declaration only available with -fconcepts
         poly inter(vector<poly> &tree, int v, auto l, auto r, auto ly, auto ry) { // auxiliary interpolation function
                                                                        ^~~~
prog.cpp:932:53: warning: use of ‘auto’ in parameter declaration only available with -fconcepts
         static poly build(vector<poly> &res, int v, auto L, auto R) { // builds evaluation tree for (x-a1)(x-a2)...(x-an)
                                                     ^~~~
prog.cpp:932:61: warning: use of ‘auto’ in parameter declaration only available with -fconcepts
         static poly build(vector<poly> &res, int v, auto L, auto R) { // builds evaluation tree for (x-a1)(x-a2)...(x-an)
                                                             ^~~~
prog.cpp: In static member function ‘static std::pair<std::vector<algebra::poly<T> >, algebra::poly<T>::transform> algebra::poly<T>::half_gcd(algebra::poly<T>, algebra::poly<T>)’:
prog.cpp:468:18: warning: structured bindings only available with -std=c++17 or -std=gnu++17
             auto [ar, Tr] = half_gcd(A.div_xk(m), B.div_xk(m));
                  ^
prog.cpp:473:18: warning: structured bindings only available with -std=c++17 or -std=gnu++17
             auto [ai, R] = A.divmod(B);
                  ^
prog.cpp:476:18: warning: structured bindings only available with -std=c++17 or -std=gnu++17
             auto [as, Ts] = half_gcd(A.div_xk(k), B.div_xk(k));
                  ^
prog.cpp: In static member function ‘static std::pair<std::vector<algebra::poly<T> >, algebra::poly<T>::transform> algebra::poly<T>::full_gcd(algebra::poly<T>, algebra::poly<T>)’:
prog.cpp:488:26: warning: structured bindings only available with -std=c++17 or -std=gnu++17
                     auto [a, Tr] = half_gcd(A, B);
                          ^
prog.cpp:493:26: warning: structured bindings only available with -std=c++17 or -std=gnu++17
                     auto [a, R] = A.divmod(B);
                          ^
prog.cpp: In member function ‘algebra::poly<T> algebra::poly<T>::min_rec_slow(int) const’:
prog.cpp:521:22: warning: structured bindings only available with -std=c++17 or -std=gnu++17
                 auto [a, nR] = R1.divmod(R2); // R1 = a*R2 + nR, deg nR < deg R2
                      ^
prog.cpp: In member function ‘algebra::poly<T> algebra::poly<T>::min_rec(int) const’:
prog.cpp:558:18: warning: structured bindings only available with -std=c++17 or -std=gnu++17
             auto [a, Tr] = full_gcd(R1, R2);
                  ^
prog.cpp: In static member function ‘static T algebra::poly<T>::kth_rec(algebra::poly<T>, algebra::poly<T>, int64_t)’:
prog.cpp:1009:22: warning: structured bindings only available with -std=c++17 or -std=gnu++17
                 auto [Q0, Q1] = Q.mulx(-1).bisect();
                      ^
prog.cpp:1010:22: warning: structured bindings only available with -std=c++17 or -std=gnu++17
                 auto [P0, P1] = P.bisect();
                      ^
prog.cpp:1014:36: error: missing template arguments before ‘(’ token
                 auto Q0f = fft::dft(Q0.a, N);
                                    ^
prog.cpp:1015:36: error: missing template arguments before ‘(’ token
                 auto Q1f = fft::dft(Q1.a, N);
                                    ^
prog.cpp:1016:36: error: missing template arguments before ‘(’ token
                 auto P0f = fft::dft(P0.a, N);
                                    ^
prog.cpp:1017:36: error: missing template arguments before ‘(’ token
                 auto P1f = fft::dft(P1.a, N);
                                    ^
prog.cpp: In member function ‘algebra::poly<T> algebra::poly<T>::inv(int) const’:
prog.cpp:1036:18: warning: structured bindings only available with -std=c++17 or -std=gnu++17
             auto [P0, P1] = Q.mulx(-1).bisect();
                  ^
prog.cpp:1040:32: error: missing template arguments before ‘(’ token
             auto P0f = fft::dft(P0.a, N);
                                ^
prog.cpp:1041:32: error: missing template arguments before ‘(’ token
             auto P1f = fft::dft(P1.a, N);
                                ^
prog.cpp:1043:32: error: missing template arguments before ‘(’ token
             auto TTf = fft::dft(( // Q(x)*Q(-x) = Q0(x^2)^2 - x^2 Q1(x^2)^2
                                ^
prog.cpp: In static member function ‘static algebra::poly<T> algebra::poly<T>::compose_large(algebra::poly<T>, algebra::poly<T>, int)’:
prog.cpp:1083:18: warning: structured bindings only available with -std=c++17 or -std=gnu++17
             auto [B0, B1] = make_pair(B.mod_xk(q), B.div_xk(q));
                  ^
prog.cpp: In lambda function:
prog.cpp:1096:22: warning: structured bindings only available with -std=c++17 or -std=gnu++17
                 auto [f0, f1] = make_pair(f.mod_xk(k), f.div_xk(k));
                      ^
prog.cpp:1097:22: warning: structured bindings only available with -std=c++17 or -std=gnu++17
                 auto [A, B] = make_pair(compose_dac(f0, k, N), compose_dac(f1, m - k, N - k));
                      ^
prog.cpp: At global scope:
prog.cpp:1126:35: warning: use of ‘auto’ in parameter declaration only available with -fconcepts
     static auto operator * (const auto& a, const poly<auto>& b) {
                                   ^~~~
prog.cpp:1126:55: warning: use of ‘auto’ in parameter declaration only available with -fconcepts
     static auto operator * (const auto& a, const poly<auto>& b) {
                                                       ^~~~
prog.cpp: In function ‘int main()’:
prog.cpp:1173:12: warning: ignoring return value of ‘FILE* freopen(const char*, const char*, FILE*)’, declared with attribute warn_unused_result [-Wunused-result]
     freopen("TRE.inp","r",stdin);
     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~
prog.cpp:1174:12: warning: ignoring return value of ‘FILE* freopen(const char*, const char*, FILE*)’, declared with attribute warn_unused_result [-Wunused-result]
     freopen("TRE.out","w",stdout);
     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
stdout
Standard output is empty