HDU5384-Hotaru's problem-Manacher
找出紧挨的三个回文串,例如abccbaabc ,形如ABA格式,其中AB为回文串。计算最长的长度。
首先用Manacher处理回文半径。然后就是找到两个点,都是偶数的回文串,并且共享了中间一段。
之后拿set搞一下就可以了= =
1 #include <set> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 7 using namespace std; 8 9 const int maxn = 1e5+10; 10 int Ma[maxn<<2],Mp[maxn<<2]; 11 set <int> pos; 12 13 struct node{ 14 int mp,p; 15 node(){} 16 bool operator < (const node &rhs) const 17 { 18 if(mp == rhs.mp) return p > rhs.p; 19 else return mp < rhs.mp; 20 } 21 }; 22 23 priority_queue<node> pq; 24 void Manacher(int s[],int len) 25 { 26 int l = 0; 27 Ma[l++] = '$'; 28 Ma[l++] = '#'; 29 for(int i=0;i<len;i++) 30 { 31 Ma[l++] = s[i]; 32 Ma[l++] = '#'; 33 } 34 Ma[l] = 0; 35 int mx = 0,id = 0; 36 for(int i=0;i<l;i++) 37 { 38 Mp[i] = mx > i? min(Mp[2*id-i],mx-i) : 1; 39 while(Ma[i + Mp[i]] == Ma[i-Mp[i]]) Mp[i]++; 40 if(Mp[i] + i > mx) 41 { 42 mx = Mp[i] + i; 43 id = i; 44 } 45 } 46 } 47 48 int T,N; 49 int save[maxn]; 50 int main() 51 { 52 scanf("%d",&T); 53 int cas = 0; 54 while(T--) 55 { 56 scanf("%d",&N); 57 for(int i=0;i<N;i++) scanf("%d",&save[i]); 58 Manacher(save,N); 59 int ans = 0; 60 node tmp; 61 while(!pq.empty()) pq.pop(); 62 pos.clear(); 63 for(int i=0;i<2*N+1;i++) 64 { 65 if(Ma[i] == '#' && Mp[i] > 1) 66 { 67 tmp.mp = Mp[i]; 68 tmp.p = i; 69 pq.push(tmp); 70 } 71 } 72 int cnt = 0; 73 //for(int i=0;i<2*N+1;i++) printf("%d\t",i); puts(""); 74 //for(int i=0;i<2*N+1;i++) printf("%c\t",Ma[i]=='#'?'#':Ma[i]+'0'); puts(""); 75 //for(int i=0;i<2*N+1;i++) printf("%d\t",Mp[i]); puts(""); 76 while(!pq.empty()) 77 { 78 tmp = pq.top(); pq.pop(); 79 int cur = tmp.p,mp = tmp.mp; 80 //printf("cur:%d mp:%d\n",cur,mp); 81 int tmp_pos = 0; 82 if(cnt) 83 { 84 auto it = pos.lower_bound(cur - (mp-1) ); 85 86 //printf("L:%d ",*it); 87 if(it != pos.end() && *it >= cur-(mp-1)) ans = max(ans,cur-*it); 88 89 it = pos.lower_bound(cur + (mp-1) ); it--; 90 //printf("R:%d\n",*it); 91 if(it != pos.end() && *it <= cur+(mp-1)) ans = max(ans,*it-cur); 92 } 93 pos.insert(cur); 94 cnt++; 95 } 96 printf("Case #%d: %d\n",++cas,ans/2*3); 97 } 98 }