zoukankan      html  css  js  c++  java
  • bzoj 2342: [Shoi2011]双倍回文 -- manacher

    2342: [Shoi2011]双倍回文

    Time Limit: 10 Sec  Memory Limit: 128 MB

    Description

    Input

    输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容。

     

    Output

    输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文子串不存在,则输出0

    Sample Input

    16
    ggabaabaabaaball

    Sample Output

    12

    HINT

    N<=500000

    Source

    首先我们manacher处理出每个位置的最长回文串

    然后我们枚举对称轴,根据题意可以知道对称轴一定在两个字符中间(即"#"处)

    并对于每边分别枚举对称轴,判断是否合法

    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 1000100
    int n,mx,md,p[N],ans;
    char c[N],s[N];
    int main()
    {
        scanf("%d%s",&n,s+1);c[0]='*';
        for(int i=1;i<=n;i++){c[(i<<1)-1]='#';c[i<<1]=s[i];}
        n<<=1;c[++n]='#';c[++n]='!';
        for(int i=1;i<n;i++)
        {
            p[i]=mx>i?min(p[(md<<1)-i],mx-i):1;
            while(c[i-p[i]]==c[i+p[i]]) p[i]++;
            if(p[i]+i>mx) mx=p[i]+i,md=i;
        }
        for(int i=1;i<n;i+=2)
        {
            int j=p[i]>>1;if(j&1) j--;
            for(;j&&j*2>ans;j-=2)
                if(p[i-j]>j&&p[i+j]>j) ans=max(ans,j<<1);
        }
        printf("%d
    ",ans);
        return 0;
    }

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    分词器下载地址
    solr 查询方式
    solr 到 lucene
    Solr 安装与使用 Centos7
    线性表-串:KMP模式匹配算法
    金山——弱智的翻译程序
    FL2440移植Linux2.6.33.7内核
    FL2440移植u-boot2011.09
    【转】C/C++除法实现方式及负数取模详解
    循环缓冲类
  • 原文地址:https://www.cnblogs.com/lkhll/p/6799207.html
Copyright © 2011-2022 走看看