zoukankan      html  css  js  c++  java
  • 「BZOJ 2342」「SHOI 2011」双倍回文「Manacher」

    题意

    (s_R)(s)翻转后的串,求一个串最长的形如(ss_Rss_R)的子串长度

    题解

    这有一个复杂度明显(O(n))的做法,思路来自网上某篇博客

    一个双倍回文串肯定当且仅当本身是一个回文串且左右两边都是回文串

    所以对于右边的回文串,到它中心(i)的时候,(manacher)记录的(maxr)一定(>i)

    如果满足这个条件,那就判断(i)(i)关于(mid)的对称串是否有交点,有交点就说明这是双倍回文串;还要注意不能以字母为中心,因为回文串必须偶数长度

    欢迎(hack)

    #include <algorithm>
    #include <cstdio>
    using namespace std;
    
    const int N = 1e6 + 10;
    
    int n, f[N];
    char c[N >> 1], s[N];
    
    int main() {
        scanf("%d%s", &n, c + 1);
        for(int i = 1; i <= n; i ++) {
            s[i * 2 - 1] = '%';
            s[i * 2] = c[i];
        }
        s[n = n * 2 + 1] = '%';
        int r = 0, mid = 0, ans = 0;
        for(int i = 1; i <= n; i += 2) {
            f[i] = i < r ? min(f[mid + mid - i], r - i) : 1;
            if(i < r && i - f[i] < mid) {
                ans = max(ans, 2 * (i - mid));
            }
            for(; i - f[i] >= 1 && i + f[i] <= n && s[i - f[i]] == s[i + f[i]]; f[i] ++) ;
            if(i + f[i] > r) r = i + f[mid = i];
        }
        printf("%d
    ", ans);
        return 0;
    }
    
    
  • 相关阅读:
    博客园的界面设置
    ARM 汇编指令集
    winfroms更换皮肤
    面向对象的七项设计原则
    S2-01
    机票查询与订购系统
    重点语法
    第二章
    一、17.09.13
    习作
  • 原文地址:https://www.cnblogs.com/hongzy/p/10372755.html
Copyright © 2011-2022 走看看