Skip to content

Commit ce16606

Browse files
Merge pull request #324 from iamrahul8/patch-1
Added circular palindrome cpp
2 parents d3f8300 + 939c582 commit ce16606

File tree

1 file changed

+183
-0
lines changed

1 file changed

+183
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
//Hackerrank Problem - Circular Palindromes
2+
// Level - Hard
3+
#include <algorithm>
4+
#include <iostream>
5+
#include <cassert>
6+
#include <cstdlib>
7+
#include <cstring>
8+
#include <cstdio>
9+
#include <cmath>
10+
#include <queue>
11+
#include <map>
12+
#include <set>
13+
14+
using namespace std;
15+
16+
#define type(x) __typeof((x).begin())
17+
#define foreach(i, x) for(type(x) i = (x).begin(); i != (x).end(); i++)
18+
#define hash ___hash
19+
20+
typedef long long ll;
21+
typedef pair < int, int > ii;
22+
23+
const int inf = 1e9 + 333;
24+
const ll linf = 1e18 + 333;
25+
26+
const int N = 2e6 + 5;
27+
28+
int n;
29+
char s[N];
30+
bool h[N];
31+
int go_odd[N], go_even[N], tmp[N << 1], rad[N << 1], ans[2][N];
32+
33+
void manacher() {
34+
memset(tmp, 0, sizeof(tmp));
35+
memset(rad, 0, sizeof(rad));
36+
int m = n * 2 + 1;
37+
for(int i = 0; i < m; i++)
38+
tmp[i] = '#';
39+
for(int i = 0; i < n; i++)
40+
tmp[i * 2 + 1] = s[i + 1];
41+
int i = 0, j = 0;
42+
while(i < m) {
43+
while(i - j >= 0 and i + j < m and tmp[i - j] == tmp[i + j])
44+
j++;
45+
rad[i] = j;
46+
int k = 1;
47+
while(rad[i - k] < rad[i] - k) {
48+
rad[i + k] = rad[i - k];
49+
k++;
50+
}
51+
i += k;
52+
j = max(0, j - k);
53+
}
54+
for(int i = 1; i <= n; i++)
55+
go_odd[i] = rad[(i - 1) * 2 + 1] / 2;//abcba --> go_odd[3] = 3
56+
for(int i = 1; i <= n; i++)
57+
go_even[i - 1] = rad[(i - 1) * 2] / 2;//abccba --> go_even[3] = 3
58+
}
59+
60+
void solveOdd(bool w) {
61+
int oth = 0;
62+
set < ii > go;
63+
for(int i = 1; i <= (n + 1) / 2; i++) {
64+
go.insert({go_odd[i], i});
65+
}
66+
for(int i = 1; i <= n; i++) {
67+
while(go.size()) {
68+
int x = go.rbegin() -> first;
69+
int id = go.rbegin() -> second;
70+
if(id < i) {
71+
go.erase(*go.rbegin());
72+
continue;
73+
}
74+
int mx = (id - i + 1) * 2 - 1;
75+
if(x > mx) {
76+
oth = max(oth, id);
77+
go.erase(*go.rbegin());
78+
continue;
79+
}
80+
break;
81+
}
82+
if(go.size())
83+
ans[w][i] = max(ans[w][i], go.rbegin() -> first);
84+
if(oth >= i)
85+
ans[w][i] = max(ans[w][i], (oth - i + 1) * 2 - 1);
86+
//printf("ans[%d] = %d oth = %d\n", i, ans[w][i]);
87+
int add = (n + 1) / 2 + i;
88+
go.insert({go_odd[add], add});
89+
}
90+
}
91+
92+
int get(int x, int y) {
93+
y -= x - 1;
94+
return min(y, n - y) * 2;
95+
}
96+
97+
void solveEven(bool w) {
98+
int oth = 0;
99+
set < ii > go;
100+
for(int i = 1; i <= (n + 1) / 2; i++) {
101+
go.insert({go_even[i], i});
102+
}
103+
for(int i = 1; i <= n; i++) {
104+
while(go.size()) {
105+
int x = go.rbegin() -> first;
106+
int id = go.rbegin() -> second;
107+
if(id < i) {
108+
go.erase(*go.rbegin());
109+
continue;
110+
}
111+
int mx = get(i, id);
112+
if(x > mx) {
113+
oth = max(oth, id);
114+
go.erase(*go.rbegin());
115+
continue;
116+
}
117+
break;
118+
}
119+
if(go.size())
120+
ans[w][i] = max(ans[w][i], go.rbegin() -> first);
121+
if(oth >= i)
122+
ans[w][i] = max(ans[w][i], get(i, oth));
123+
//printf("ans[%d] = %d\n", i, ans[w][i]);
124+
int add = (n + 1) / 2 + i;
125+
go.insert({go_even[add], add});
126+
}
127+
}
128+
129+
130+
int main () {
131+
132+
scanf("%d %s", &n, s + 1);
133+
134+
for(int i = 1; i <= n; i++)
135+
s[i + n] = s[i];
136+
137+
138+
n *= 2;
139+
manacher();
140+
n /= 2;
141+
142+
for(int i = 1; i <= n + n; i++) {
143+
go_odd[i] *= 2;
144+
go_odd[i] -= 1;
145+
go_even[i] *= 2;
146+
}
147+
148+
solveOdd(0);
149+
solveEven(0);
150+
151+
152+
153+
reverse(s + 1, s + n * 2 + 1);
154+
155+
n *= 2;
156+
manacher();
157+
n /= 2;
158+
159+
for(int i = 1; i <= n + n; i++) {
160+
go_odd[i] *= 2;
161+
go_odd[i] -= 1;
162+
go_even[i] *= 2;
163+
}
164+
165+
solveOdd(1);
166+
solveEven(1);
167+
168+
printf("%d\n", max(ans[0][1], ans[1][1]));
169+
170+
for(int i = 2; i <= n; i++) {
171+
printf("%d\n", max(ans[0][i], ans[1][n + 2 - i]));
172+
}
173+
174+
return 0;
175+
176+
}
177+
178+
179+
180+
181+
182+
183+

0 commit comments

Comments
 (0)