http://acm.hdu.edu.cn/showproblem.php?pid=5340
/* Manacher算法:O(n) 实现最长回文子串 算法实现: 先向原字符串中插入一个原来串不存在的字符,一般用‘#‘,再O(n)遍历一遍,用一个数组p[i]来记录以str[i]为中心的回文半径(注意str[i]是新串,长度为2*len+1),mx记录当前已有的回文最长到的位置,假定当前为i,j为i前面已经计算过的数,id为最长的回文的中心,那么可以得到一个方程 p[i] = min(p[2*id-i],mx - i),p[2*id-i]与p[i]是关于id对称的,那么p[i]的回文长度就是p[2*id-1]的回文长度,可是如果p[i]的长度超过了p[id]的mx,那么右边的就不确定了,然后再向外扩展 */ /************************************************ * Author :Powatr * Created Time :2015-8-12 13:11:42 * File Name :Manacher.cpp ************************************************/ #include <cstdio> #include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cmath> #include <string> #include <vector> #include <queue> #include <deque> #include <stack> #include <list> #include <map> #include <set> #include <bitset> #include <cstdlib> #include <ctime> using namespace std; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 typedef long long ll; const int MAXN = 1e5 + 10; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; int pre1[MAXN], pre2[MAXN]; int p[MAXN]; char s[MAXN]; char str[MAXN]; int n; void inti() { memset(str, 0, sizeof(str)); memset(p, 0, sizeof(p)); memset(pre1, 0, sizeof(pre1)); memset(pre2, 0, sizeof(pre2)); n = strlen(s+1); str[0] = ‘$‘; for(int i = 1; i <= n; i++){ str[i*2-1] = ‘#‘; str[i*2] = s[i]; } n = 2*n+1; str[n] = ‘#‘;str[n+1] = ‘\0‘; } void Manacher() { int mx = 0, id; for(int i = 1; i <= n; i++){ if(mx > i) p[i] = min(p[2*id-i], mx-i); else p[i] = 1; for(; str[i+p[i]] == str[i-p[i]]; p[i]++); if(p[i] + i > mx){ mx = p[i] + i; id = i; } } } bool check() { int cout1 = 0, cout2 = 0; for(int i = 1; i <= n; i++){ if(p[i] == i && i != 1){// printf("%d ", i); pre1[++cout1] = i;} if(i + p[i] - 1 == n && i != n) pre2[++cout2] = i; } int l, r, mid; for(int i = 1; i <= cout1; i++){ for(int j = 1; j <= cout2; j++){ l = pre1[i] + p[pre1[i]] ; r = pre2[j] - p[pre2[j]] ; if(l > r) continue; mid = l + r >> 1; if(p[mid] > (r - l + 1 >> 1)){//这边是大于,因为p[mid]包含了自己 return true; } } } return false; } int main(){ int T; scanf("%d", &T); while(T--){ scanf("%s", s+1); n = strlen(s+1); if(n < 3) {printf("No\n");continue;} inti(); Manacher(); if(check()) printf("Yes\n"); else printf("No\n"); } return 0; }
时间: 2024-10-31 11:16:44