Skip to content

Commit 3127bac

Browse files
committed
add
1 parent 74dc1ed commit 3127bac

7 files changed

+105
-8
lines changed

docs/fps/sampling-points-shift.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
以下の問題を $O((N+M)\log(N+M))$ 時間で解く.
2+
3+
> 次数 $N$ 未満の多項式 $f(x)$ について $f(0),f(1),\dots,f(N-1)$ が与えられる.
4+
> $f(c),f(c+1),\dots,f(c+M-1)$ を列挙せよ.
5+
6+
## アルゴリズム
7+
8+
下降階乗冪を用いて $f(x)=\sum_{i=0}^{N-1}a_ix^{\underline{i}}$ とおくと $0\leq i\lt N$ に対し
9+
10+
$$f(k)=k!\sum_{i=0}^{k}\frac{a_i}{(k-i)!}$$
11+
12+
が成り立つため,$a_i$ は
13+
14+
$$a_i=[x^i]e^{-x}\sum_{k=0}^{N-1}\frac{f(k)}{k!}x^k$$
15+
16+
として計算できる.
17+
18+
また下降階乗冪について $(a+b)^{\underline{n}}=\sum_{i=0}^{n}\binom{n}{i}a^{\underline{i}}b^{\underline{n-i}}$ が成り立つため,$f(x+c)=\sum_{i=0}^{N-1}b_ix^{\underline{i}}$ とおくと
19+
20+
$$b_i=\frac{1}{i!}\sum_{j}(i+j)!a_{i+j}\cdot\frac{c^{\underline{j}}}{j!}$$
21+
22+
が成り立つ.あとは $a_i$ の計算の逆をすればよい.

fps/relaxed.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,6 @@ class RelaxedSqrt {
200200
};
201201

202202
/**
203-
* @brief Relaxed 畳み込み
203+
* @brief Relaxed
204204
* @docs docs/fps/relaxed.md
205205
*/

fps/sampling-points-shift.hpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#pragma once
2+
#include "modint/factorial.hpp"
3+
#include "fps/formal-power-series.hpp"
4+
5+
// f(0),f(1),...,f(n-1) -> f(c),...,f(c+m-1)
6+
template <class mint>
7+
vector<mint> SamplingPointsShift(const vector<mint>& f, mint c, int m) {
8+
using fps = FormalPowerSeries<mint>;
9+
using fact = Factorial<mint>;
10+
int n = f.size();
11+
fact::reserve(m);
12+
fps f1(n), ei(n);
13+
for (int i = 0; i < n; i++) f1[i] = f[i] * fact::fact_inv(i);
14+
for (int i = 0; i < n; i++) ei[i] = fact::fact_inv(i) * (i % 2 ? -1 : 1);
15+
f1 *= ei;
16+
for (int i = n; i < f1.size(); i++) f1[i] = 0;
17+
for (int i = 0; i < n; i++) f1[i] *= fact::fact(i);
18+
fps g(n, 1);
19+
for (int i = 1; i < n; i++) g[i] = g[i - 1] * (c + 1 - i) * fact::inv(i);
20+
g = g.middle_product(f1);
21+
for (int i = 0; i < n; i++) g[i] *= fact::fact_inv(i);
22+
fps e(m);
23+
for (int i = 0; i < m; i++) e[i] = fact::fact_inv(i);
24+
g *= e;
25+
g.resize(m);
26+
for (int i = 0; i < m; i++) g[i] *= fact::fact(i);
27+
return g;
28+
}
29+
/**
30+
* @brief 評価点シフト
31+
* @docs docs/fps/sampling-points-shift.md
32+
*/

math/stern-brocot-tree.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ struct SternBrocotTreeNode {
2424
}
2525
SternBrocotTreeNode(pair<T, T> p) : SternBrocotTreeNode(p.first, p.second) {}
2626
SternBrocotTreeNode(const vector<T> seq_) {
27-
for (auto &v : seq_) {
27+
for (auto& v : seq_) {
2828
assert(v != 0);
2929
if (v > 0)
3030
go_right(v);
@@ -53,10 +53,10 @@ struct SternBrocotTreeNode {
5353
}
5454
T depth() const {
5555
T d = 0;
56-
for (auto &v : seq) d += abs(v);
56+
for (auto& v : seq) d += abs(v);
5757
return d;
5858
}
59-
static Node lca(const Node &x, const Node &y) {
59+
static Node lca(const Node& x, const Node& y) {
6060
Node res;
6161
for (int i = 0; i < min(x.seq.size(), y.seq.size()); i++) {
6262
T d1 = x.seq[i], d2 = y.seq[i];
@@ -110,7 +110,7 @@ struct SternBrocotTreeNode {
110110
}
111111
}
112112
}
113-
}; // namespace SternBrocotTree
113+
};
114114

115115
/**
116116
* @brief Stern-Brocot Tree
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#define PROBLEM "https://judge.yosupo.jp/problem/division_of_polynomials"
2+
3+
#include "template/template.hpp"
4+
#include "modint/modint.hpp"
5+
using mint = ModInt<998244353>;
6+
#include "fps/fps-ntt-friendly.hpp"
7+
using fps = FormalPowerSeries<mint>;
8+
9+
int main() {
10+
int n, m;
11+
in(n, m);
12+
fps f(n), g(m);
13+
in(f, g);
14+
fps q = f / g;
15+
q.shrink();
16+
fps r = f - g * q;
17+
r.shrink();
18+
out(q.size(), r.size());
19+
out(q);
20+
out(r);
21+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#define PROBLEM "https://judge.yosupo.jp/problem/shift_of_sampling_points_of_polynomial"
2+
3+
#include "template/template.hpp"
4+
#include "modint/modint.hpp"
5+
using mint = ModInt<998244353>;
6+
#include "fps/fps-ntt-friendly.hpp"
7+
using fps = FormalPowerSeries<mint>;
8+
#include "fps/sampling-points-shift.hpp"
9+
10+
int main() {
11+
int n, m;
12+
mint c;
13+
in(n, m, c);
14+
vector<mint> f(n);
15+
in(f);
16+
auto g = SamplingPointsShift(f, c, m);
17+
out(g);
18+
}

verify/fps/LC_sqrt_of_formal_power_series.relaxed.test.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,14 @@ int main() {
1313
in(n);
1414
fps a(n);
1515
in(a);
16-
if (ModSqrt(a[0].val(), mint::get_mod()) == -1) {
16+
if (a[0] == 0) {
17+
a = FpsSqrt(a);
18+
if (a.empty())
19+
out(-1);
20+
else
21+
out(a);
22+
} else if (ModSqrt(a[0].val(), mint::get_mod()) == -1) {
1723
out(-1);
18-
} else if (a[0] == 0) {
19-
out(FpsSqrt(a));
2024
} else {
2125
fps b(n);
2226
RelaxedSqrt<mint> sqrt;

0 commit comments

Comments
 (0)