Skip to content

Commit be6314c

Browse files
committed
Fixes
1 parent 21a66df commit be6314c

File tree

3 files changed

+50
-18
lines changed

3 files changed

+50
-18
lines changed

cp-algo/math/fft.hpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,9 @@ namespace cp_algo::math::fft {
271271
}
272272
void mul_truncate(auto &a, auto const& b, size_t k) {
273273
using base = std::decay_t<decltype(a[0])>;
274-
auto n = std::max(flen, std::bit_ceil(k) / 2);
274+
auto n = std::max(flen, std::bit_ceil(
275+
std::min(k, size(a)) + std::min(k, size(b)) - 1
276+
) / 2);
275277
auto A = dft<base>(std::views::take(a, k), n);
276278
if(size(a) != k) {
277279
a.resize(k);
@@ -283,12 +285,9 @@ namespace cp_algo::math::fft {
283285
}
284286
}
285287
void mul(auto &a, auto const& b) {
286-
if(size(a) || size(b)) {
288+
if(size(a)) {
287289
mul_truncate(a, b, size(a) + size(b) - 1);
288290
}
289291
}
290-
void circular_mul(auto &a, auto const& b) {
291-
mul_truncate(a, b, std::max(size(a), size(b)));
292-
}
293292
}
294293
#endif // CP_ALGO_MATH_FFT_HPP

cp-algo/math/poly.hpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -202,19 +202,29 @@ namespace cp_algo::math {
202202
return poly_t(*this).log_inplace(n);
203203
}
204204

205-
poly_t exp(size_t n) const { // calculate exp p(x) mod x^n
205+
poly_t& mul_truncate(poly_t const& t, size_t k) {
206+
fft::mul_truncate(a, t.a, k);
207+
normalize();
208+
return *this;
209+
}
210+
211+
poly_t& exp_inplace(size_t n) {
206212
if(is_zero()) {
207-
return T(1);
213+
return *this = T(1);
208214
}
209215
assert(a[0] == T(0));
210-
poly_t ans = T(1);
216+
a[0] = 1;
211217
size_t a = 1;
212218
while(a < n) {
213-
poly_t C = ans.log(2 * a).div_xk(a) - substr(a, 2 * a);
214-
ans -= (ans * C).mod_xk(a).mul_xk(a);
219+
poly_t C = log(2 * a).div_xk_inplace(a) - substr(a, 2 * a);
220+
*this -= C.mul_truncate(*this, a).mul_xk_inplace(a);
215221
a *= 2;
216222
}
217-
return ans.mod_xk(n);
223+
return mod_xk_inplace(n);
224+
}
225+
226+
poly_t exp(size_t n) const { // calculate exp p(x) mod x^n
227+
return poly_t(*this).exp_inplace(n);
218228
}
219229

220230
poly_t pow_bin(int64_t k, size_t n) const { // O(n log n log k)
@@ -537,13 +547,6 @@ namespace cp_algo::math {
537547
return a * b.reverse();
538548
}
539549

540-
// [x^k] (a semicorr b) = sum_i a{i+k} * b{i}
541-
static poly_t inner_semicorr(poly_t const& a, poly_t const& b) {
542-
auto ta = a.a;
543-
fft::circular_mul(ta, b.reverse().a);
544-
return poly_t(ta).div_xk(b.deg());
545-
}
546-
547550
// [x^k] (a semicorr b) = sum_i a{i+k} * b{i}
548551
static poly_t semicorr(poly_t const& a, poly_t const& b) {
549552
return corr(a, b).div_xk(b.deg());

verify/poly/exp.test.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// @brief Exp of Power Series
2+
#define PROBLEM "https://judge.yosupo.jp/problem/exp_of_formal_power_series"
3+
#pragma GCC optimize("Ofast,unroll-loops")
4+
#include "cp-algo/math/poly.hpp"
5+
#include <bits/stdc++.h>
6+
7+
using namespace std;
8+
using namespace cp_algo::math;
9+
10+
const int mod = 998244353;
11+
using base = modint<mod>;
12+
using polyn = poly_t<base>;
13+
14+
void solve() {
15+
int n;
16+
cin >> n;
17+
vector<base> a(n);
18+
copy_n(istream_iterator<base>(cin), n, begin(a));
19+
polyn(a).exp_inplace(n).print(n);
20+
}
21+
22+
signed main() {
23+
//freopen("input.txt", "r", stdin);
24+
ios::sync_with_stdio(0);
25+
cin.tie(0);
26+
int t = 1;
27+
while(t--) {
28+
solve();
29+
}
30+
}

0 commit comments

Comments
 (0)