HDU 3068 最长回文

Manacher算法练笔,O(n)求最长回文子串。

参考资料:http://blog.csdn.net/ggggiqnypgjg/article/details/6645824

http://www.felix021.com/blog/read.php?2040

 

后缀数组和拓展KMP也可以求,不过时间复杂度都是O(nlogn)。

 1 #include <cstdio>

 2 #include <cstring>

 3 

 4 const int MAXN = 110010;

 5 

 6 char s[MAXN];

 7 char str[ MAXN << 1 ];

 8 int p[ MAXN << 1 ];

 9 int newL, n;

10 

11 int min( int a, int b )

12 {

13     return a < b ? a : b;

14 }

15 

16 int max( int a, int b )

17 {

18     return a > b ? a : b;

19 }

20 

21 void init()

22 {

23     int i;

24     str[0] = '?';

25     str[1] = '#';

26     newL = 2;

27     for ( i = 1; s[i]; ++i )

28     {

29         str[ newL++ ] = s[i];

30         str[ newL++ ] = '#';

31     }

32     str[ newL ] = '\0';

33     n = newL;

34 

35     return;

36 }

37 

38 void DP()

39 {

40     int maxID = 0, id;

41     for ( int i = 1; i < newL; ++i )

42     {

43         if ( maxID > i ) p[i] = min( p[ (id << 1) - i ], p[id] + id - i );

44         else p[i] = 1;

45 

46         while ( str[ i + p[i] ] == str[ i - p[i] ] ) ++p[i];

47         if ( p[i] + i > maxID )

48         {

49             maxID = p[i] + i;

50             id = i;

51         }

52     }

53     return;

54 }

55 

56 int main()

57 {

58     while ( ~scanf( "%s", &s[1] ) )

59     {

60         init();

61         DP();

62 

63         int maxL = 0;

64         for ( int i = 1; i < n; ++i )

65             maxL = max( maxL, p[i] - 1 );

66         printf( "%d\n", maxL );

67     }

68     return 0;

69 }

 

你可能感兴趣的:(HDU)