1
1
#ifndef CP_ALGO_MATH_POLY_HPP
2
2
#define CP_ALGO_MATH_POLY_HPP
3
3
#include " poly/impl/euclid.hpp"
4
- #include " poly/impl/base.hpp"
5
4
#include " poly/impl/div.hpp"
6
5
#include " combinatorics.hpp"
7
6
#include " ../number_theory/discrete_sqrt.hpp"
@@ -19,42 +18,60 @@ namespace cp_algo::math {
19
18
using base = T;
20
19
std::vector<T> a;
21
20
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
+ }
23
27
24
28
poly_t (){}
25
29
poly_t (T a0): a{a0} {normalize ();}
26
30
poly_t (std::vector<T> const & t): a(t) {normalize ();}
27
31
poly_t (std::vector<T>&& t): a(std::move(t)) {normalize ();}
28
32
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
+ }
32
50
poly_t operator + (poly_t const & t) const {return poly_t (*this ) += t;}
33
51
poly_t operator - (poly_t const & t) const {return poly_t (*this ) -= t;}
34
52
35
53
poly_t & mod_xk_inplace (size_t k) {
36
54
a.resize (std::min (size (a), k));
37
- normalize ();
38
- return *this ;
55
+ return normalize ();
39
56
}
40
57
poly_t & mul_xk_inplace (size_t k) {
41
58
a.insert (begin (a), k, T (0 ));
42
- normalize ();
43
- return *this ;
59
+ return normalize ();
44
60
}
45
61
poly_t & div_xk_inplace (int64_t k) {
46
62
if (k < 0 ) {
47
63
return mul_xk_inplace (-k);
48
64
}
49
65
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);
52
70
}
53
71
poly_t mod_xk (size_t k) const {return poly_t (*this ).mod_xk_inplace (k);}
54
72
poly_t mul_xk (size_t k) const {return poly_t (*this ).mul_xk_inplace (k);}
55
73
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);}
58
75
59
76
poly_t & operator *= (const poly_t &t) {fft::mul (a, t.a ); normalize (); return *this ;}
60
77
poly_t operator * (const poly_t &t) const {return poly_t (*this ) *= t;}
@@ -64,12 +81,21 @@ namespace cp_algo::math {
64
81
poly_t operator / (poly_t const & t) const {return poly_t (*this ) /= t;}
65
82
poly_t operator % (poly_t const & t) const {return poly_t (*this ) %= t;}
66
83
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
+ }
68
90
poly_t & operator /= (T const & x) {return *this *= x.inv ();}
69
91
poly_t operator * (T const & x) const {return poly_t (*this ) *= x;}
70
92
poly_t operator / (T const & x) const {return poly_t (*this ) /= x;}
71
93
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
+ }
73
99
poly_t & reverse () {return reverse (size (a));}
74
100
poly_t reversed (size_t n) const {return poly_t (*this ).reverse (n);}
75
101
poly_t reversed () const {return poly_t (*this ).reverse ();}
@@ -208,8 +234,7 @@ namespace cp_algo::math {
208
234
209
235
poly_t & mul_truncate (poly_t const & t, size_t k) {
210
236
fft::mul_truncate (a, t.a , k);
211
- normalize ();
212
- return *this ;
237
+ return normalize ();
213
238
}
214
239
215
240
poly_t & exp_inplace (size_t n) {
0 commit comments