题目链接:https://ac.nowcoder.com/acm/contest/33540/A
此题为manacher算法的变形,利用了算法的一部分性质,还用到了差分求前缀和。
题目链接:https://www.luogu.com.cn/problem/P3805
此题纯为manacher的模板题;
题一代码:
1 #include<iostream>
2 #include<cstdio>
3 #include<algorithm>
4 #include<vector>
5 #include<map>
6 #include<queue>
7 #include<set>
8 #include<cmath>
9 #include<list>
10 #include<cstring>
11 #include<string>
12 #define ll long long
13 #define ull unsigned long long
14 #define inf 0x3f3f3f3f
15 #define inff 0x7fffffff
16 using namespace std;
17 const int N = 1000000 + 10;
18
19 int Len[N << 4];
20
21 int ans[N << 4];
22 int b[N << 4];
23
24
25 int longestPalindrome(string s) {
26 string new_str = "";
27 new_str += "@";
28 for (int i = 0; i < s.length(); i++) {
29 new_str += "#";
30 new_str += s[i];
31 }
32 new_str += "#";
33 new_str += "$";
34 //cout << new_str << endl;
35 //new_str 存储 扩充后的字符串,如 @#a#b#a#$
36 int len = new_str.length();
37 int r = 0, mid = 0, ans = 0;//r 表示目前最右回文子串半径,mid则是该字串的中心下标,ans存储最长回文子串长度。
38 for (int i = 1; i < len - 1; i++) {
39 if (i < r) {
40 Len[i] = min(r - i, Len[2 * mid - i]);
41 }
42 else Len[i] = 1;
43
44 while (new_str[i + Len[i]] == new_str[i - Len[i]]) {
45 Len[i]++;
46 }
47 if ((i + Len[i]) > r) {
48 r = i + Len[i];
49 mid = i;
50 }
51 ans = max(ans, (Len[i] - 1));
52 }
53 return ans;
54 }
55
56 int main() {
57
58 int n;
59 cin >> n;
60 string s = "";
61 for (int i = 0; i < n; i++) {
62 int x;
63 cin >> x;
64 s += (x + '0');
65 }
66 int an = longestPalindrome(s);
67
68 /*for (int i = 0; i <= 2 * n + 1; i++) {
69 cout << Len[i] << " ";
70 }
71 cout << "\n";*/
72 for (int i = 1; i <= 2 * n + 1; i++) {
73 int l = i - Len[i] + 1;
74 int r = i;
75 b[l] += 1;
76 b[r + 1] -= 1;
77 //QjUpdate(l, r, 1, 1, 2 * n + 1, 1);
78 //if (i % 2 == 0) cout << Query(i, i, 1, 2 * n + 1, 1) << " ";
79 }
80 for (int i = 1; i <= 2 * n + 1; i++) {
81 ans[i] = ans[i - 1] + b[i];
82 if (i % 2 == 0) cout << ans[i] << " ";
83 }
84 /*for (int i = 2; i <= 2 * n; i += 2) {
85 cout << Query(i, i, 1, 2 * n + 1, 1) << " ";
86 }*/
87
88 return 0;
89 }
题二代码:
1 #include<iostream>
2 #include<cstdio>
3 #include<algorithm>
4 #include<vector>
5 #include<map>
6 #include<queue>
7 #include<set>
8 #include<cmath>
9 #include<list>
10 #include<cstring>
11 #include<string>
12 #define ll long long
13 #define ull unsigned long long
14 #define inf 0x3f3f3f3f
15 #define inff 0x7fffffff
16 using namespace std;
17 const int N = 11000000 + 10;
18
19 int Len[N << 3];
20
21 int longestPalindrome(string s) {
22 string new_str = "";
23 new_str += "@";
24 for (int i = 0; i < s.length(); i++) {
25 new_str += "#";
26 new_str += s[i];
27 }
28 new_str += "#";
29 new_str += "$";
30 //cout << new_str << endl;
31 //new_str 存储 扩充后的字符串,如 @#a#b#a#$
32 int len = new_str.length();
33 int r = 0, mid = 0, ans = 0;//r 表示目前最右回文子串半径,mid则是该字串的中心下标,ans存储最长回文子串长度。
34 for (int i = 1; i < len - 1; i++) {
35 if (i < r) {
36 Len[i] = min(r - i, Len[2 * mid - i]);
37 }
38 else Len[i] = 1;
39
40 while (new_str[i + Len[i]] == new_str[i - Len[i]]) {
41 Len[i]++;
42 }
43 if ((i + Len[i]) > r) {
44 r = i + Len[i];
45 mid = i;
46 }
47 ans = max(ans, (Len[i] - 1));
48 }
49 return ans;
50 }
51
52 int main() {
53
54 string s;
55 cin >> s;
56 int an = longestPalindrome(s);
57 cout << an << "\n";
58
59 return 0;
60 }