【HDOJ】3068 最长回文
马拉车算法O(n)可解。
1 /* 3068 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <algorithm> 11 #include <cstdio> 12 #include <cmath> 13 #include <ctime> 14 #include <cstring> 15 #include <climits> 16 #include <cctype> 17 #include <cassert> 18 #include <functional> 19 using namespace std; 20 //#pragma comment(linker,"/STACK:102400000,1024000") 21 22 #define sti set<int> 23 #define stpii set<pair<int, int> > 24 #define mpii map<int,int> 25 #define vi vector<int> 26 #define pii pair<int,int> 27 #define vpii vector<pair<int,int> > 28 #define rep(i, a, n) for (int i=a;i<n;++i) 29 #define per(i, a, n) for (int i=n-1;i>=a;--i) 30 #define clr clear 31 #define pb push_back 32 #define mp make_pair 33 #define fir first 34 #define sec second 35 #define all(x) (x).begin(),(x).end() 36 #define SZ(x) ((int)(x).size()) 37 #define lson l, mid, rt<<1 38 #define rson mid+1, r, rt<<1|1 39 40 const int maxn = 110005; 41 char s[maxn*2], ss[maxn]; 42 int P[maxn*2]; 43 int ans, l; 44 45 void init() { 46 int i, len = strlen(ss); 47 48 l = 0; 49 s[l++] = '@'; 50 s[l++] = '#'; 51 for (i=0; i<len; ++i) { 52 s[l++] = ss[i]; 53 s[l++] = '#'; 54 } 55 s[l++] = '\0'; 56 } 57 58 void manacher() { 59 int i, mx = 0, id; 60 61 for (i=1; i<l; ++i) { 62 P[i] = mx>i ? min(P[2*id-i], mx-i) : 1; 63 while (s[i+P[i]] == s[i-P[i]]) 64 ++P[i]; 65 if (i+P[i] > mx) { 66 mx = i + P[i]; 67 id = i; 68 } 69 } 70 71 ans = 0; 72 for (i=1; i<l; ++i) 73 ans = max(ans, P[i]); 74 printf("%d\n", ans-1); 75 } 76 77 void solve() { 78 init(); 79 manacher(); 80 } 81 82 int main() { 83 ios::sync_with_stdio(false); 84 #ifndef ONLINE_JUDGE 85 freopen("data.in", "r", stdin); 86 freopen("data.out", "w", stdout); 87 #endif 88 89 while (scanf("%s", ss)!=EOF) { 90 solve(); 91 } 92 93 #ifndef ONLINE_JUDGE 94 printf("time = %d.\n", (int)clock()); 95 #endif 96 97 return 0; 98 }