1 /* 2 Manacher:该算法能求最长回文串,思路时依据回文半径p数组找到第一个和第三个会文串,然后暴力枚举判断是否存在中间的回文串 3 另外,在原字符串没啥用时可以直接覆盖,省去一个数组空间,位运算 >>1 比 /2 速度快,用了程序跑快200ms左右,位运算大法好 4 */ 5 /************************************************ 6 Author :Running_Time 7 Created Time :2015-8-1 20:10:22 8 File Name :B.cpp 9 *************************************************/ 10 11 #include <cstdio> 12 #include <algorithm> 13 #include <iostream> 14 #include <sstream> 15 #include <cstring> 16 #include <cmath> 17 #include <string> 18 #include <vector> 19 #include <queue> 20 #include <deque> 21 #include <stack> 22 #include <list> 23 #include <map> 24 #include <set> 25 #include <bitset> 26 #include <cstdlib> 27 #include <ctime> 28 using namespace std; 29 30 typedef long long ll; 31 const int MAXN = 2e4 + 10; 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 char s[MAXN*2]; 35 int p[MAXN*2], fi[MAXN*2], ei[MAXN*2]; 36 int len; 37 38 void Manacher(void) { 39 for (int i=len; i>=0; --i) { 40 s[i*2+2] = s[i]; s[i*2+1] = ‘#‘; 41 } 42 s[0] = ‘$‘; len = len * 2 + 2; 43 int id = 0; p[0] = 1; 44 for (int i=2; i<len; ++i) { 45 if (id + p[id] > i) p[i] = min (p[2*id-i], id + p[id] - i); 46 else p[i] = 1; 47 while (s[i-p[i]] == s[i+p[i]]) p[i]++; 48 if (id + p[id] < i + p[i]) id = i; 49 } 50 } 51 52 bool judge(void) { 53 int c1 = 0, c2 = 0; 54 for (int i=2; i<len-1; ++i) { 55 if (p[i] == i) fi[++c1] = i; 56 if (i + p[i] == len) ei[++c2] = i; 57 } 58 for (int i=1; i<=c1; ++i) { 59 for (int j=1; j<=c2; ++j) { 60 int l = fi[i] + p[fi[i]]; 61 int r = ei[j] - p[ei[j]]; 62 if (l > r) continue; 63 int mid = (l + r) >> 1; 64 if (p[mid] > (r - l + 1) >> 1) return true; 65 } 66 } 67 return false; 68 } 69 70 int main(void) { //BestCoder Round #49 ($) 1002 Three Palindromes 71 int T; scanf ("%d", &T); 72 while (T--) { 73 scanf ("%s", s); 74 len = strlen (s); 75 if (len < 3) { 76 puts ("NO"); continue; 77 } 78 Manacher (); 79 judge () ? puts ("Yes") : puts ("No"); 80 } 81 82 return 0; 83 }
时间: 2024-12-18 00:04:54