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 }

 

posted @ 2016-08-08 19:55  Helica  阅读(164)  评论(0编辑  收藏  举报