[国家集训队]最长双回文串

题意是 求字符串 A +B = C 且 C 在序列中 A 和 B 都是回文串

运用了回文字符串优美的性质:删掉任意两个相同的字符仍然回文且长度减2

看到这题之后 我在想 如果把 A 字符串的末尾 设为 A 的长度 B 字符串的开始 设为 B 的长度

然后 设 A 字符串的 右端点 代表的长度为 \(R_i\)
设 B 字符串的 左端点 代表的长度为 \(L_i\)
然后 求 \(max\)\({L_i + R_i}\)
但是你会发现这样是不会得到最优解的 就像这样

aaaaa

答案是5 但是你只更新了 \(L_5\)\(R_1\) 的值 所以程序认为的答案不是5 是 0

这样你就要开始递推

其实你统计的信息都是在分隔符上…然后你会发现两个分隔符里有一个字符

所以你 递推式 是 \(L_i\) =max{ \(L_i\) , \(L_{i+2} - 2\)} \(R_i\) = max{\(R_i\) , \(R_{i-2}-2\)}

然后再取 \(max\)\({L_i+R_i}\)

#include<bits/stdc++.h>
using namespace std ;
#define int long long
#define fi first
#define se second
#define pb emplace_back
inline int read() {
	register char c = getchar() ;
	register int x = 0 , f = 1 ;
	for( ; ! isdigit(c) ; c = getchar()) if(c == '-') f = -1 ;
	for( ; isdigit(c) ; c = getchar()) x = (x << 1) + (x << 3) + (c & 15) ;
	return x * f ;
}
template < typename T > inline bool cmax(T & x , T y) {
	return x < y ? x = y , 1 : 0 ;
}
template < typename T > inline bool cmin(T & x , T y) {
	return x > y ? x = y , 1 : 0 ;
}
inline int QP(int x , int y , int Mod) { int ans = 1 ;
	for( ; y ; y >>= 1 , x = (x * x) % Mod)
		if(y & 1) ans = (ans * x) % Mod ;
	return ans ;
}
const int N = 2e5 + 10 ;
char s[N] , fix[N << 1] ;
int p[N << 1] ;
int L[N << 1] , R[N << 1] ;
signed main() {
	scanf("%s" , s + 1) ;
  int n = strlen(s + 1) ;
  int len = 0 ;
  fix[++ len] = '$' ;
  fix[++ len] = '%' ;
  for(register int i = 1 ; i <= n ; i ++)
    fix[++ len] = s[i] , fix[++ len] = '%' ;
  int mid = 0 , id = 0 ;
  for(register int i = 1 ; i <= len ; i ++) {
    if(i <= id) p[i] = min(p[(mid << 1) - i] , id - i + 1) ;
    while(fix[i - p[i]] == fix[i + p[i]]) p[i] ++ ;
    if(i + p[i] > id) mid = i , id = i + p[i] - 1 ;
    cmax(L[i + p[i] - 1] , p[i] - 1) ;
    cmax(R[i - p[i] + 1] , p[i] - 1) ;
  } int ans = 0 ;
  for(register int i = 2 ; i <= len ; i += 2) cmax(R[i] , R[i - 2] - 2) ;
  for(register int i = len ; i >= 1 ; i -= 2) cmax(L[i] , L[i + 2] - 2) ; 
  int QWQ = 2333 ;
  for(register int i = 1 ; i <= len ; i ++) (L[i] && R[i]) ? cmax(ans , L[i] + R[i]) : QWQ;
  printf("%lld\n" , ans) ;
	return 0 ;
}
posted @ 2019-10-10 10:40  _Isaunoya  阅读(129)  评论(0编辑  收藏  举报