Skip to content

Commit 6f748eb

Browse files
authored
Manacher algorithm for LPS
- SPOJ LPS problem worked fine until Test Case #15 got TLE - Some optimization and cleanup pending
1 parent ce12a10 commit 6f748eb

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

manacher.cpp

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include <bits/stdc++.h>
2+
#include <algorithm>
3+
using namespace std;
4+
5+
long long curren_p_len, current_palindrome_left=-1, current_palindrome_right=-1;
6+
long long max_p =0;
7+
void updateCurrentPalindrome( long long index, long long length)
8+
{
9+
long long offset = (length -1)/2;
10+
curren_p_len = length;
11+
current_palindrome_right = index+offset;
12+
current_palindrome_left = index-offset;
13+
14+
}
15+
long long findPalindromeLen( long long centre, long long skip, string a)
16+
{
17+
long long count =0;
18+
while(centre-skip-count >=0 && (a[centre-skip-count]== a[centre+skip+count]))
19+
count++;
20+
if(count)
21+
count --; //Skip the last offset
22+
return (2*(skip+count)) +1;
23+
}
24+
long long LPS(string a)
25+
{
26+
long long current_index = 0;
27+
vector<long long> len;
28+
29+
while ( current_index < a.size())
30+
{
31+
cout << current_index<<endl;
32+
if(max_p==a.size())
33+
break;
34+
if(current_index <= current_palindrome_right )
35+
{
36+
for ( long long j = current_index -2 ; j>=current_palindrome_left; j--)
37+
{
38+
// Look for new centre i.e. Rule #3;left
39+
long long offset = (len[j]-1)/2;
40+
long long myleft = j - offset;
41+
long long myright = current_index + offset;
42+
if((myleft == current_palindrome_left) && (myright== current_palindrome_right))
43+
{
44+
//Found new centre, find palindrome
45+
len.push_back(findPalindromeLen(current_index, offset, a));
46+
updateCurrentPalindrome(current_index, len[current_index]);
47+
break;
48+
}
49+
else if ((myleft>= current_palindrome_left) && (myright<= current_palindrome_right))
50+
{
51+
52+
//Current index totally lies in palindrom boundary ; just copy the palindrom length
53+
len.push_back(len [j]);
54+
current_index++;
55+
//updateCurrentPalindrome(current_index, len[current_index]);
56+
}
57+
else
58+
{
59+
// Calculate length
60+
len.push_back( len[j] - (2* (current_palindrome_left-myleft)));
61+
current_index++;
62+
}
63+
}
64+
}
65+
else
66+
{
67+
// Do normal
68+
len.push_back(findPalindromeLen(current_index, 0, a));
69+
updateCurrentPalindrome(current_index, len[current_index]);
70+
}
71+
if(max_p< len[current_index])
72+
max_p =len[current_index];
73+
current_index++;
74+
}// while loop ends
75+
#ifdef DEBUG
76+
for ( long long i=0; i<a.size();i++)
77+
cout << len[i]<<" ";
78+
#endif
79+
return max_p;
80+
}
81+
int main(int argc, char*argv[])
82+
{
83+
ios_base::sync_with_stdio(false);
84+
cin.tie(NULL);
85+
// long long l;
86+
//cin >>l;
87+
string a;
88+
cin >>a;
89+
if(a.size()%2) // Odd len string
90+
cout <<LPS(a);
91+
else
92+
{
93+
string s;
94+
for ( long long i=0; i< (2*a.size())+1;i++)
95+
s.push_back(i%2?a[i/2]:'$');
96+
cout << LPS(s)/2;
97+
98+
}
99+
}//$a$a$

0 commit comments

Comments
 (0)