BotByte

Manacher

May 3rd, 2018
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.18 KB | None | 0 0
  1. //manacher's algo
  2.  
  3. // Finds all palindromes in a string
  4. //
  5. // Given a string s of length N, finds all palindromes as its substrings.
  6. //
  7. // After calling manacher(s, N, rad), rad[x] will be the radius of the largest
  8. // palindrome centered at index x / 2.
  9. // Example:
  10. //   s   = b a n a n a a
  11. //   rad = 0000102010010
  12. //
  13. // Note: Array rad must be of length at least twice the length of the string.
  14. // Also, "invalid" characters are denoted by -1, therefore the string must not
  15. // contain such characters.
  16. //
  17. // Time complexity: O(N)
  18. //
  19. // Constants to configure:
  20. // - MAX is the maximum length of the string
  21.  
  22.  
  23. #define FOR(i, a, b) for (int i = (a); i < (b); ++i)
  24. #define REP(i, n) FOR(i, 0, n)
  25.  
  26. typedef long long llint;
  27.  
  28. void manacher(char *s, int N, int *rad) {
  29.   static char t[2*MAX];
  30.   int m = 2*N - 1;
  31.  
  32.   REP(i, m) t[i] = -1;
  33.   REP(i, N) t[2*i] = s[i];
  34.  
  35.   int x = 0;
  36.   FOR(i, 1, m) {
  37.     int &r = rad[i] = 0;
  38.     if (i <= x+rad[x]) r = min(rad[x+x-i], x+rad[x]-i);
  39.     while (i-r-1 >= 0 && i+r+1 < m && t[i-r-1] == t[i+r+1]) ++r;
  40.     if (i+r >= x+rad[x]) x = i;
  41.   }
  42.  
  43.   REP(i, m) if (i-rad[i] == 0 || i+rad[i] == m-1) ++rad[i];
  44.   REP(i, m) rad[i] /= 2;
  45. }
Advertisement
Add Comment
Please, Sign In to add comment