这个比最长回文子串就多了一个条件,就是回文字串(这里相当于人的高度)由两端向中间递增。
才刚刚看了看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 ", 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 ", 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 ", ans); 94 } 95 return 0; 96 }