11#ifndef CP_ALGO_MATH_POLY_HPP
22#define CP_ALGO_MATH_POLY_HPP
33#include " poly/impl/euclid.hpp"
4- #include " poly/impl/base.hpp"
54#include " poly/impl/div.hpp"
65#include " combinatorics.hpp"
76#include " ../number_theory/discrete_sqrt.hpp"
@@ -19,42 +18,60 @@ namespace cp_algo::math {
1918 using base = T;
2019 std::vector<T> a;
2120
22- void normalize () {poly::impl::normalize (*this );}
21+ poly_t & normalize () {
22+ while (deg () >= 0 && lead () == base (0 )) {
23+ a.pop_back ();
24+ }
25+ return *this ;
26+ }
2327
2428 poly_t (){}
2529 poly_t (T a0): a{a0} {normalize ();}
2630 poly_t (std::vector<T> const & t): a(t) {normalize ();}
2731 poly_t (std::vector<T>&& t): a(std::move(t)) {normalize ();}
2832
29- poly_t operator -() const {return poly::impl::neg_inplace (poly_t (*this ));}
30- poly_t & operator += (poly_t const & t) {return poly::impl::add (*this , t);}
31- poly_t & operator -= (poly_t const & t) {return poly::impl::sub (*this , t);}
33+ poly_t & negate_inplace () {
34+ std::ranges::transform (a, begin (a), std::negate{});
35+ return *this ;
36+ }
37+ poly_t operator -() const {
38+ return poly_t (*this ).negate_inplace ();
39+ }
40+ poly_t & operator += (poly_t const & t) {
41+ a.resize (std::max (size (a), size (t.a )));
42+ std::ranges::transform (a, t.a , begin (a), std::plus{});
43+ return normalize ();
44+ }
45+ poly_t & operator -= (poly_t const & t) {
46+ a.resize (std::max (size (a), size (t.a )));
47+ std::ranges::transform (a, t.a , begin (a), std::minus{});
48+ return normalize ();
49+ }
3250 poly_t operator + (poly_t const & t) const {return poly_t (*this ) += t;}
3351 poly_t operator - (poly_t const & t) const {return poly_t (*this ) -= t;}
3452
3553 poly_t & mod_xk_inplace (size_t k) {
3654 a.resize (std::min (size (a), k));
37- normalize ();
38- return *this ;
55+ return normalize ();
3956 }
4057 poly_t & mul_xk_inplace (size_t k) {
4158 a.insert (begin (a), k, T (0 ));
42- normalize ();
43- return *this ;
59+ return normalize ();
4460 }
4561 poly_t & div_xk_inplace (int64_t k) {
4662 if (k < 0 ) {
4763 return mul_xk_inplace (-k);
4864 }
4965 a.erase (begin (a), begin (a) + std::min<size_t >(k, size (a)));
50- normalize ();
51- return *this ;
66+ return normalize ();
67+ }
68+ poly_t &substr_inplace (size_t l, size_t k) {
69+ return mod_xk_inplace (l + k).div_xk_inplace (l);
5270 }
5371 poly_t mod_xk (size_t k) const {return poly_t (*this ).mod_xk_inplace (k);}
5472 poly_t mul_xk (size_t k) const {return poly_t (*this ).mul_xk_inplace (k);}
5573 poly_t div_xk (int64_t k) const {return poly_t (*this ).div_xk_inplace (k);}
56-
57- poly_t substr (size_t l, size_t k) const {return poly::impl::substr (*this , l, k);}
74+ poly_t substr (size_t l, size_t k) const {return poly_t (*this ).substr_inplace (l, k);}
5875
5976 poly_t & operator *= (const poly_t &t) {fft::mul (a, t.a ); normalize (); return *this ;}
6077 poly_t operator * (const poly_t &t) const {return poly_t (*this ) *= t;}
@@ -64,12 +81,21 @@ namespace cp_algo::math {
6481 poly_t operator / (poly_t const & t) const {return poly_t (*this ) /= t;}
6582 poly_t operator % (poly_t const & t) const {return poly_t (*this ) %= t;}
6683
67- poly_t & operator *= (T const & x) {return *this = poly::impl::scale (*this , x);}
84+ poly_t & operator *= (T const & x) {
85+ for (auto &it: a) {
86+ it *= x;
87+ }
88+ return normalize ();
89+ }
6890 poly_t & operator /= (T const & x) {return *this *= x.inv ();}
6991 poly_t operator * (T const & x) const {return poly_t (*this ) *= x;}
7092 poly_t operator / (T const & x) const {return poly_t (*this ) /= x;}
7193
72- poly_t & reverse (size_t n) {return poly::impl::reverse (*this , n);}
94+ poly_t & reverse (size_t n) {
95+ a.resize (n);
96+ std::ranges::reverse (a);
97+ return normalize ();
98+ }
7399 poly_t & reverse () {return reverse (size (a));}
74100 poly_t reversed (size_t n) const {return poly_t (*this ).reverse (n);}
75101 poly_t reversed () const {return poly_t (*this ).reverse ();}
@@ -208,8 +234,7 @@ namespace cp_algo::math {
208234
209235 poly_t & mul_truncate (poly_t const & t, size_t k) {
210236 fft::mul_truncate (a, t.a , k);
211- normalize ();
212- return *this ;
237+ return normalize ();
213238 }
214239
215240 poly_t & exp_inplace (size_t n) {
0 commit comments