hdu5371

来源:互联网 发布:ij scan utility 软件 编辑:程序博客网 时间:2024/06/07 05:36

题意:找三个连续子序列a b c,满足a b对称且b c对称

思路:先求出序列中以每个位置为中心的回文串长度存在p[i]数组里,用manacher算法,O(n)的时间,然后遍历p数组,如果在当前位置的回文串范围内,与之后的位置上的回文串范围能覆盖彼此任意一个的至少一半,就说明满足条件,依此找出最优解

还在wa的同学可以试试我代码下面的数据

代码:

#include <algorithm>#include <iostream>#include <sstream>#include <cstdlib>#include <cstring>#include <iomanip>#include <cstdio>#include <string>#include <bitset>#include <vector>#include <queue>#include <stack>#include <cmath>#include <list>#include <map>#include <set>#define sss(a,b,c) scanf("%d%d%d",&a,&b,&c)#define mem1(a) memset(a,-1,sizeof(a))#define mem(a) memset(a,0,sizeof(a))#define ss(a,b) scanf("%d%d",&a,&b)#define s(a) scanf("%d",&a)#define p(a) printf("%d\n", a)#define INF 0x3f3f3f3f#define w(a) while(a)#define PI acos(-1.0)#define LL long long#define eps 10E-9#define N 1000000+20#define mod 1000000007#define _min(x, y) ((x)<(y)?(x):(y))using namespace std;void mys(int& res){    int flag=0;    char ch;    while(!(((ch=getchar())>='0'&&ch<='9')||ch=='-'))        if(ch==EOF)  res=INF;    if(ch=='-')  flag=1;    else if(ch>='0'&&ch<='9')  res=ch-'0';    while((ch=getchar())>='0'&&ch<='9')  res=res*10+ch-'0';    res=flag?-res:res;}void myp(int a){    if(a>9)        myp(a/10);    putchar(a%10+'0');}/*************************THE END OF TEMPLATE************************/int n, p[N];int s[N];int str[N];void kp(){    int i;    int mx = 0;    int id; //   for(i=n; str[i]!=0; i++) //       str[i] = 0;    for(i=1; i<n; i++)    {        if( mx > i )            p[i] = _min( p[2*id-i], p[id]+id-i );        else            p[i] = 1;        for(; str[i+p[i]] == str[i-p[i]]; p[i]++)            ;        if( p[i] + i > mx )        {            mx = p[i] + i;            id = i;        }    }}void init(){    int i, j, k;    str[0] = -1;    str[1] = -2;    for(i=0; i<n; i++)    {        str[i*2+2] = s[i];        str[i*2+3] = -2;    }    n = n*2+2;    s[n] = 0;}int main(){    int t;    int time=1;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        for(int i=0;i<n;i++)  s(s[i]);        init();//manacher模板        kp();//manacher模板        int top = 0;        for(int i=1; i<n; i+=2){//枚举加优化              if((p[i]-1)>1 && !((p[i]-1)%2)){//回文串长度必然要大于一并且为偶数                    for(int j=p[i]-1; j>top; j-=2){//当目前解小于top时就没必要进行了,继续走会超时                         if(p[j+i]-1 >= j) {                                top = (j);                                break;                         }                    }              }        }        printf("Case #%d: ",time++);        printf("%d\n",top/2*3);    }    return 0;}/*1131 2 2 1 1 2 3 3 2 1 1 2 31111 1 2 1 1 2 1 1 2 1 1*/



1 0
原创粉丝点击