利用Manacher求出每两个数字中间位置的回文长度
之后利用set进行维护,大题思路如下:
要满足题目所要求的内容,需要使得两个相邻的回文串,共享中间的一部分,比如上边的两个字符串,共享 8 9 10这一部分。 也就是说,左边的回文串长度的一半,要大于等于共享部分的长度,右边回文串也是一样。 因为我们已经记录下来以第i个点和第i+1个点为中心的回文串长度, 那么问题可以转化成,相距x的两个数a[i],a[i+x],满足a[i]/2>=x 并且 a[i+x]/2>=x,要求x尽量大
这可以用一个set维护,一开始集合为空,依次取出a数组中最大的元素,将其下标放入set中,每取出一个元素,再该集合中二分查找比i+a[i]/2小,但最大的元素,更新答案。 然后查找集合中比i-a[i]/2大,但最小的元素,更新答案。
但是据说数据比较水,所以可以用可能退化成 O(n2) 的枚举方法也可以过。
参考官方题解:http://bestcoder.hdu.edu.cn/blog/
// whn6325689
// Mr.Phoebe
// http://blog.csdn.net/u013007900
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#include <functional>
#include <numeric>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define eps 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LLINF 1LL<<62
#define speed std::ios::sync_with_stdio(false);
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef complex<ld> point;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef vector<int> vi;
#define CLR(x,y) memset(x,y,sizeof(x))
#define CPY(x,y) memcpy(x,y,sizeof(x))
#define clr(a,x,size) memset(a,x,sizeof(a[0])*(size))
#define cpy(a,x,size) memcpy(a,x,sizeof(a[0])*(size))
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define lowbit(x) (x&(-x))
#define MID(x,y) (x+((y-x)>>1))
#define ls (idx<<1)
#define rs (idx<<1|1)
#define lson ls,l,mid
#define rson rs,mid+1,r
#define root 1,1,n
template<class T>
inline bool read(T &n)
{
T x = 0, tmp = 1;
char c = getchar();
while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
if(c == EOF) return false;
if(c == '-') c = getchar(), tmp = -1;
while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
n = x*tmp;
return true;
}
template <class T>
inline void write(T n)
{
if(n < 0)
{
putchar('-');
n = -n;
}
int len = 0,data[20];
while(n)
{
data[len++] = n%10;
n /= 10;
}
if(!len) data[len++] = 0;
while(len--) putchar(data[len]+48);
}
//-----------------------------------
const int MAXN=200010;
int num[MAXN],dst[MAXN];
int n,len[MAXN];
set<int> st;
pii pos[MAXN];
void Manacher(int *s)
{
int l=0;
dst[l++]=-2;dst[l++]=-1;
for(int i=0;i<n;i++)
{
dst[l++]=s[i];
dst[l++]=-1;
}
int mx=0,po=0;
for(int i=0;i<l;i++)
{
len[i]=mx>i?min(mx-i,len[2*po-i]):1;
while(dst[i-len[i]]==dst[i+len[i]])
len[i]++;
if(len[i]+i>mx)
{
mx=len[i]+i;
po=i;
}
}
}
int main()
{
freopen("data.txt","r",stdin);
int T,cas=1;
scanf("%d",&T);
while(T--)
{
st.clear();CLR(len,0);
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&num[i]);
Manacher(num);
for(int i=0;i<n;i++)
{
pos[i]=mp((len[i*2+1]-1)/2,i);
}
sort(pos,pos+n);
int ans=0;
set<int>::iterator it,it1;
for(int i=n-1;i>=0;i--)
{
st.insert(pos[i].second);
it=(st.lower_bound(pos[i].second-pos[i].first));
it1=(st.upper_bound(pos[i].second+pos[i].first));
it1--;
ans=max(ans,*it1-pos[i].second);
ans=max(ans,pos[i].second-*it);
}
printf("Case #%d: %d\n",cas++,3*ans);
}
return 0;
}
枚举法
// whn6325689
// Mr.Phoebe
// http://blog.csdn.net/u013007900
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#include <functional>
#include <numeric>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define eps 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LLINF 1LL<<62
#define speed std::ios::sync_with_stdio(false);
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef complex<ld> point;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef vector<int> vi;
#define CLR(x,y) memset(x,y,sizeof(x))
#define CPY(x,y) memcpy(x,y,sizeof(x))
#define clr(a,x,size) memset(a,x,sizeof(a[0])*(size))
#define cpy(a,x,size) memcpy(a,x,sizeof(a[0])*(size))
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define lowbit(x) (x&(-x))
#define MID(x,y) (x+((y-x)>>1))
#define ls (idx<<1)
#define rs (idx<<1|1)
#define lson ls,l,mid
#define rson rs,mid+1,r
#define root 1,1,n
template<class T>
inline bool read(T &n)
{
T x = 0, tmp = 1;
char c = getchar();
while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
if(c == EOF) return false;
if(c == '-') c = getchar(), tmp = -1;
while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
n = x*tmp;
return true;
}
template <class T>
inline void write(T n)
{
if(n < 0)
{
putchar('-');
n = -n;
}
int len = 0,data[20];
while(n)
{
data[len++] = n%10;
n /= 10;
}
if(!len) data[len++] = 0;
while(len--) putchar(data[len]+48);
}
//-----------------------------------
const int MAXN=100007;
int num[MAXN<<1];
int tmp[MAXN<<1];
int len[MAXN<<1];
int n;
void manacher(int *st,int *dst)
{
int l=0;
dst[l++]=-2;dst[l++]=-1;
for(int i=0;i<n;i++)
{
dst[l++]=st[i];
dst[l++]=-1;
}
int mx=0,po=0;
for(int i=0;i<l;i++)
{
len[i]=mx>i?min(mx-i,len[2*po-i]):1;
while(dst[i-len[i]]==dst[i+len[i]])
len[i]++;
if(len[i]+i>mx)
{
mx=len[i]+i;
po=i;
}
}
}
int main ()
{
freopen("data.txt","r",stdin);
int T,cas=1;
read(T);
while(T--)
{
read(n);
for(int i=0;i<n;i++)
read(num[i]);
manacher(num,tmp);
int ans=0,l=2*n+1;
for(int i=1;i<=l;i+=2)
for(int j=i+len[i]-1;j-i>ans;j-=2)
if(j-i+1<=len[j])
{
ans=j-i;
break;
}
ans=ans/2*3;
printf("Case #%d: %d\n",cas++,ans);
}
return 0;
}