@@ -33,9 +33,25 @@ namespace cp_algo::math {
33
33
poly_t operator + (poly_t const & t) const {return poly_t (*this ) += t;}
34
34
poly_t operator - (poly_t const & t) const {return poly_t (*this ) -= t;}
35
35
36
- poly_t mod_xk (size_t k) const {return poly::impl::mod_xk (*this , k);} // %= x^k
37
- poly_t mul_xk (size_t k) const {return poly::impl::mul_xk (*this , k);} // *= x^k
38
- poly_t div_xk (size_t k) const {return poly::impl::div_xk (*this , k);} // /= x^k
36
+ poly_t & mod_xk_inplace (size_t k) {
37
+ a.resize (std::min (size (a), k));
38
+ normalize ();
39
+ return *this ;
40
+ }
41
+ poly_t & mul_xk_inplace (size_t k) {
42
+ a.insert (begin (a), k, T (0 ));
43
+ normalize ();
44
+ return *this ;
45
+ }
46
+ poly_t & div_xk_inplace (size_t k) {
47
+ a.erase (begin (a), min (k, size (a)));
48
+ normalize ();
49
+ return *this ;
50
+ }
51
+ poly_t mod_xk (size_t k) const {return poly_t (*this ).mod_xk_inplace (k);}
52
+ poly_t mul_xk (size_t k) const {return poly_t (*this ).mul_xk_inplace (k);}
53
+ poly_t div_xk (size_t k) const {return poly_t (*this ).div_xk_inplace (k);}
54
+
39
55
poly_t substr (size_t l, size_t k) const {return poly::impl::substr (*this , l, k);}
40
56
41
57
poly_t operator *= (const poly_t &t) {fft::mul (a, t.a ); normalize (); return *this ;}
@@ -135,17 +151,28 @@ namespace cp_algo::math {
135
151
bool operator == (const poly_t &t) const {return a == t.a ;}
136
152
bool operator != (const poly_t &t) const {return a != t.a ;}
137
153
138
- poly_t deriv (int k = 1 ) const { // calculate derivative
154
+ poly_t & deriv_inplace (int k = 1 ) {
139
155
if (deg () + 1 < k) {
140
- return poly_t ( T ( 0 )) ;
156
+ return * this = poly_t {} ;
141
157
}
142
- std::vector<T> res (deg () + 1 - k);
143
158
for (int i = k; i <= deg (); i++) {
144
- res [i - k] = fact<T>(i) * rfact<T>(i - k) * a[i];
159
+ a [i - k] = fact<T>(i) * rfact<T>(i - k) * a[i];
145
160
}
146
- return res;
161
+ a.resize (deg () + 1 - k);
162
+ return *this ;
163
+ }
164
+ poly_t deriv (int k = 1 ) const { // calculate derivative
165
+ return poly_t (*this ).deriv_inplace (k);
166
+ }
167
+
168
+ poly_t & integr_inplace () {
169
+ a.push_back (0 );
170
+ for (int i = deg () - 1 ; i >= 0 ; i--) {
171
+ a[i + 1 ] = a[i] * small_inv<T>(i + 1 );
172
+ }
173
+ a[0 ] = 0 ;
174
+ return *this ;
147
175
}
148
-
149
176
poly_t integr () const { // calculate integral with C = 0
150
177
std::vector<T> res (deg () + 2 );
151
178
for (int i = 0 ; i <= deg (); i++) {
@@ -165,9 +192,15 @@ namespace cp_algo::math {
165
192
return res;
166
193
}
167
194
168
- poly_t log (size_t n) const { // calculate log p(x) mod x^n
195
+ // calculate log p(x) mod x^n
196
+ poly_t log_inplace (size_t n) {
169
197
assert (a[0 ] == T (1 ));
170
- return (mod_xk (n).deriv () * inv (n)).mod_xk (n - 1 ).integr ();
198
+ auto t = mod_xk_inplace (n).inv (n);
199
+ deriv_inplace ();
200
+ return (*this *= t).mod_xk_inplace (n - 1 ).integr_inplace ();
201
+ }
202
+ poly_t log (size_t n) const {
203
+ return poly_t (*this ).log_inplace (n);
171
204
}
172
205
173
206
poly_t exp (size_t n) const { // calculate exp p(x) mod x^n
@@ -585,8 +618,7 @@ namespace cp_algo::math {
585
618
586
619
// inverse series mod x^n
587
620
poly_t & inv_inplace (size_t n) {
588
- poly::impl::inv_inplace (*this , n);
589
- return *this ;
621
+ return poly::impl::inv_inplace (*this , n);
590
622
}
591
623
poly_t inv (size_t n) const {
592
624
return poly_t (*this ).inv_inplace (n);
0 commit comments