HDU4513吉哥系列故事――完美队形II(manacher算法)

这个比最长回文子串就多了一个条件,就是回文字串(这里相当于人的高度)由两端向中间递增。

才刚刚看了看manacher,在用模板A了一道题后,还没有完全理解manacher,然后就准备把这道题也直接带模板的。

却发现这个递增的要求实在是麻烦,然后实在是没办法了,就把manacher算法拆开了,写两遍,按照子串的中间是一个数还是两个数来写。

其他的什么地方都没改,只是扩展的时候把题目要求的条件加上就好了。

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <vector>
 8 #include <cstdio>
 9 #include <cctype>
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 #define INF 0x3f3f3f3f
16 #define inf (-((LL)1<<40))
17 #define lson k<<1, L, mid
18 #define rson k<<1|1, mid+1, R
19 #define mem0(a) memset(a,0,sizeof(a))
20 #define mem1(a) memset(a,-1,sizeof(a))
21 #define mem(a, b) memset(a, b, sizeof(a))
22 #define FOPENIN(IN) freopen(IN, "r", stdin)
23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
24 
25 template<class T> T CMP_MIN(T a, T b) { return a < b; }
26 template<class T> T CMP_MAX(T a, T b) { return a > b; }
27 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
28 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
29 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
30 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
31 
32 //typedef __int64 LL;
33 typedef long long LL;
34 const int MAXN = 4000000+10;
35 const int MAXM = 2000010;
36 const double eps = 1e-12;
37 
38 int high[MAXN];
39 int rad[MAXN];
40 int T, N;
41 
42 int manacherOdd()
43 {
44     mem0(rad);
45     for(int i=1,j=0,k;i<=N;)
46     {
47         while (high[i-j-1]==high[i+j+1] && high[i-j]>=high[i-j-1]) j++;  //扫描得出rad值
48         rad[i]=j;
49         for (k=1; k<=j && rad[i-k]!=rad[i]-k; k++) rad[i+k]=min(rad[i-k],rad[i]-k);  //k指针扫描
50         i+=k;  //i跳到下一个需要计算rad值的位置
51         j=max(j-k,0);  //更新下一个rad值的初始值
52         //printf("%d\n", i);
53     }
54     int ans = 0;
55     for(int i=1;i<=N;i++)
56     {
57         ans = max(ans, rad[i]*2+1);
58     }
59     return ans;
60 }
61 
62 int manacherEven()
63 {
64     mem0(rad);
65     int j = 0, k;
66     for(int i=1;i<N;)
67         if(high[i]==high[i+1])
68         {
69             while(high[i-j-1] == high[i+j+2] && high[i-j]>=high[i-j-1]) j++;
70             rad[i] = j+1;
71             for(k=1;k<=j && rad[i-k]!=rad[i]-k; k++) rad[i+k]=min(rad[i-k],rad[i]-k);
72             i += k;
73             j = max(j-k, 0);
74             //printf("%d\n", i);
75         }
76         else i++;
77     int ans = 0;
78     for(int i=1;i<=N;i++)
79     {
80         ans = max(ans, rad[i]*2);
81     }
82     return ans;
83 }
84 
85 int main()
86 {
87     while(~scanf("%d", &T))while(T--)
88     {
89         scanf("%d", &N);
90         for(int i=1;i<=N;i++) scanf("%d", &high[i]);
91         high[0] = high[N+1] = INF;
92         int ans = max( manacherOdd(), manacherEven());
93         printf("%d\n", ans);
94     }
95     return 0;
96 }

 

posted @ 2014-03-25 13:14  再见~雨泉  阅读(495)  评论(0编辑  收藏  举报