hdu5371

来源:互联网 发布:魔域一条龙网站源码 编辑:程序博客网 时间:2024/06/06 20:15

这道题目当时做的时候先用manacher处理过,但是之后的求法太有问题了,所以一直WA。
我们可以发现,题目中所给的三部分,其实就是两个回文子串,我们这样定义这个N-sequence
。。。i。。。j。。。,把i当做第一个回文子串的中心(用mancher处理过后,相当于这里是另外新加的一个数字),j为第二个回文子串的中心,那么我们先将i+p[i] (p[i]为以i为中心的回文子串半径),那么从i+p[i]位置往前找,找到一个j,是的j-i>=len[j],这样子,i与j之间所夹的那个子串就是在i左边和j右边共用的回文子串中的一般,此时三部分中的一部分的长度就为(j-i)/2 (除以2是因为用manacher处理过后,有一半的数字是自己加上去的),然后最后再乘以3即可。

#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>#include<time.h>#include<queue>#include<stack>#include<iterator>#include<math.h>#include<stdlib.h>#include<limits.h>#include<map>#include<set>//#define ONLINE_JUDGE#define eps 1e-8#define INF 0x7fffffff#define FOR(i,a) for((i)=0;i<(a);(i)++)#define MEM(a) (memset((a),0,sizeof(a)))#define sfs(a) scanf("%s",a)#define sf(a) scanf("%d",&a)#define sfI(a) scanf("%I64d",&a)#define pf(a) printf("%d\n",a)#define pfI(a) printf("%I64d\n",a)#define pfs(a) printf("%s\n",a)#define sfd(a,b) scanf("%d%d",&a,&b)#define sft(a,b,num) scanf("%d%d%d",&a,&b,&num)#define for1(i,a,b) for(int i=(a);i<b;i++)#define for2(i,a,b) for(int i=(a);i<=b;i++)#define for3(i,a,b)for(int i=(b);i>=a;i--)#define MEM1(a) memset(a,0,sizeof(a))#define MEM2(a) memset(a,-1,sizeof(a))#define ll __int64const double PI=acos(-1.0);template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}template<class T> inline T Min(T a,T b){return a<b?a:b;}template<class T> inline T Max(T a,T b){return a>b?a:b;}using namespace std;int n,m;#define M 110#define N 100010#define Mod 1000000007#define p(x,y) make_pair(x,y)int a[N];int p[2*N],ch[2*N];int tot;void manacher(){    memset(p,0,sizeof p);    for(int i=1,j=0,k;i<tot;){            while(i-j-1>=0 && i+j+1<tot && ch[i-j-1] == ch[i+j+1])                j++;         p[i] = j;         for(k=1;k<=j && i-k>=0 && p[i]-k!=p[i-k];k++){             p[i+k] = Min(p[i-k],p[i]-k);         }         i += k;         j = Max(j-k,0);    }}int main(){#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);//  freopen("out.txt", "w", stdout);#endif    int t;    int kas=1;    sf(t);    while(t--){        sf(n);        for(int i=0;i<n;i++)            sf(a[i]);        tot=0;        ch[tot++] = INF;        for(int i=0;i<n;i++){            ch[tot++] = a[i];            ch[tot++] = INF;        }        manacher();        int ans=0;        for(int i=0;i<tot;i+=2){    //枚举的时候只要枚举新加进去的数即可,因为都是以它们作为回文子串中心的            for(int j=i+p[i];j-i>ans;j-=2){                if(j-i<=p[j]){                    ans = j-i;                    break;                }            }        }        ans = ans/2*3;        printf("Case #%d: ",kas++);        pf(ans);    }    return 0;}
0 0