2015多校第7场 HDU 5371 Segment Game 思维,Manacher算法

来源:互联网 发布:医院机关哪好 知乎 编辑:程序博客网 时间:2024/05/17 23:37

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5371

题意:求形如ABA(B与A对称0)的串的最大长度。

解法:先用manacher预处理出以每个点为中心的最长回文子串长度,枚举第二个部分即B的起点,再枚举串的长度,发现可行则更新答案(代码中非常清楚了)。可以用已经得到的ans剪枝。我求答案的时候用i++,j--枚举T了,改成i+=2,j-=2过了。。


#include <bits/stdc++.h>using namespace std;const int maxn = 2e5+10;typedef long long LL;struct FastIO{    static const int S = 1310720;    int wpos;    char wbuf[S];    FastIO() : wpos(0) {}    inline int xchar()    {        static char buf[S];        static int len = 0, pos = 0;        if (pos == len)            pos = 0, len = fread(buf, 1, S, stdin);        if (pos == len) return -1;        return buf[pos ++];    }    inline int xuint()    {        int c = xchar(), x = 0;        while (c <= 32) c = xchar();        for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';        return x;    }    inline int xint()    {        int s = 1, c = xchar(), x = 0;        while (c <= 32) c = xchar();        if (c == '-') s = -1, c = xchar();        for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';        return x * s;    }    inline void xstring(char *s)    {        int c = xchar();        while (c <= 32) c = xchar();        for (; c > 32; c = xchar()) * s++ = c;        *s = 0;    }    inline void wchar(int x)    {        if (wpos == S) fwrite(wbuf, 1, S, stdout), wpos = 0;        wbuf[wpos ++] = x;    }    inline void wint(LL x)    {        if (x < 0) wchar('-'), x = -x;        char s[24];        int n = 0;        while (x || !n) s[n ++] = '0' + x % 10, x /= 10;        while (n--) wchar(s[n]);    }    inline void wstring(const char *s)    {        while (*s) wchar(*s++);    }    ~FastIO()    {        if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;    }} io;int s[maxn], str[maxn];int len1,len2,p[maxn],ans;void init(){    str[0]=-1;    str[1]=-1;    for(int i=0; i<len1; i++){        str[i*2+2]=s[i];        str[i*2+3]=-1;    }    len2=len1*2+2;    str[len2]=-1;}void manacher(){    int id=0,mx=0;    for(int i=1; i<len2; i++){        if(mx>i) p[i]=min(p[2*id-i],mx-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;        }    }}int main(){    int T,n,ks=0;    T = io.xint();    while(T--){        n = io.xint();        for(int i=0; i<n; i++){            s[i] = io.xint();        }        len1=n;        init();        manacher();        ans=0;        for(int i=1; i<len2; i+=2){            for(int j=p[i]+i-1; j-i>ans; j-=2){                if(j-i+1<=p[j]){                    ans = max(ans, j-i);                    break;                }            }        }        printf("Case #%d: %d\n", ++ks, ans/2*3);    }    return 0;}


原创粉丝点击