Skip to content

Commit a60ddf5

Browse files
authored
Merge pull request #410 from hitonanode/fix-manacher
Fix manacher
2 parents d60fa82 + 455f8a4 commit a60ddf5

File tree

5 files changed

+36
-4
lines changed

5 files changed

+36
-4
lines changed

graph/test/shortest_path_dial.yuki1695.test.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ int solve(const string &S, const string &T) {
1414
if (!nmatch) return INF;
1515
if (T.size() % 2) return INF;
1616
auto trev = T;
17+
reverse(trev.begin(), trev.end());
1718
if (trev != T) return INF;
1819
shortest_path<int> graph(T.size() + 1);
1920
for (int i = 0; i < int(T.size()); ++i) graph.add_edge(i, i + 1, 0);
@@ -23,7 +24,7 @@ int solve(const string &S, const string &T) {
2324
if ((l + r) % 2 == 0) graph.add_edge(r, (l + r) / 2, 1);
2425
}
2526
graph.dial(T.size(), nmatch);
26-
return graph.dist[nmatch];
27+
return std::max(1, graph.dist[nmatch]);
2728
}
2829

2930
int main() {

graph/test/zero_one_bfs.yuki1695.test.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ int solve(const string &S, const string &T) {
1414
if (!nmatch) return INF;
1515
if (T.size() % 2) return INF;
1616
auto trev = T;
17+
reverse(trev.begin(), trev.end());
1718
if (trev != T) return INF;
1819
shortest_path<int> graph(T.size() + 1);
1920
for (int i = 0; i < int(T.size()); ++i) graph.add_edge(i, i + 1, 0);
@@ -23,7 +24,7 @@ int solve(const string &S, const string &T) {
2324
if ((l + r) % 2 == 0) graph.add_edge(r, (l + r) / 2, 1);
2425
}
2526
graph.zero_one_bfs(T.size(), nmatch);
26-
return graph.dist[nmatch];
27+
return std::max(1, graph.dist[nmatch]);
2728
}
2829

2930
int main() {

string/manacher.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#include <utility>
44
#include <vector>
55

6-
// CUT begin
76
// Manacher's Algorithm: radius of palindromes
87
// Input: std::string or std::vector<T> of length N
98
// Output: std::vector<int> of size N
@@ -30,8 +29,13 @@ std::vector<int> manacher(const std::string &S) {
3029
return manacher(v);
3130
}
3231

32+
// Find maximal palindrome length for each center
33+
// input: array of length N
34+
// output: array of length N * 2 - 1
3335
template <typename T>
3436
std::vector<std::pair<int, int>> enumerate_palindromes(const std::vector<T> &vec) {
37+
if (vec.empty()) return {};
38+
3539
std::vector<T> v;
3640
const int N = vec.size();
3741
for (int i = 0; i < N - 1; i++) {
@@ -52,7 +56,6 @@ std::vector<std::pair<int, int>> enumerate_palindromes(const std::vector<T> &vec
5256
}
5357
return ret;
5458
}
55-
5659
std::vector<std::pair<int, int>> enumerate_palindromes(const std::string &S) {
5760
std::vector<char> v(S.size());
5861
for (int i = 0; i < int(S.size()); i++) v[i] = S[i];

string/manacher.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ for (auto [l, r] : palindromes) {
1616
}
1717
```
1818

19+
## 問題例
20+
21+
- [Enumerate Palindromes](https://judge.yosupo.jp/problem/enumerate_palindromes)
22+
- [No.3392 Count 23578 Sequence - yukicoder](https://yukicoder.me/problems/no/3392)
23+
1924
## 文献
2025

2126
- [1] G. Manacher, "A new linear-time "on-line" algorithm for finding the smallest initial palindrome of a string", Journal of the ACM, 22 (3), 346-351, 1975.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#define PROBLEM "https://yukicoder.me/problems/no/3392"
2+
#include "../manacher.hpp"
3+
4+
#include <iostream>
5+
using namespace std;
6+
7+
int main() {
8+
cin.tie(nullptr), ios::sync_with_stdio(false);
9+
10+
int N;
11+
cin >> N;
12+
vector<int> A(N);
13+
for (auto &a : A) cin >> a;
14+
15+
vector<int> D(N - 1);
16+
for (int i = 0; i < N - 1; ++i) D.at(i) = A.at(i + 1) - A.at(i);
17+
18+
long long ret = N;
19+
for (auto [l, r] : enumerate_palindromes(D)) ret += (r - l + 1) / 2;
20+
21+
cout << ret << '\n';
22+
}

0 commit comments

Comments
 (0)