zoukankan      html  css  js  c++  java
  • HDU 3068 最长回文(马拉车模板题)

    马拉车可以求出每个字符为中心的最长回文串 

    # 1 # 2 # 2 # 1 # 2 # 2 #
    1 2 1 2 5 2 1 6 1 2 3 2 1

    '#'字符对应的p[i]对应的回文串在原串s里都是偶数长度的,而'1','2'对应的p[i]对应的回文串在原串s里都是奇数长度的

    总结O(n)求最长回文子串,关键是p[i]数组,p[i]表示的是处理过的字符串t里以i位置字符为中心的最长回文子串半径然后,p[i]-1得到的就是以i位置字符为中心的最长回文子串长度(在s串里),然后如果要确定一个回文子串的位置的话,起始位置是中间位置减去半径再除以2,即(i-p[i])/2,这个是该回文子串在s串里的起始位置,s和t都是从0下标开始放的。

    #include<bits/stdc++.h>
    using namespace std;
    #define ls rt<<1
    #define rs (rt<<1)+1
    #define PI acos(-1)
    #define eps 1e-8
    #define ll long long
    #define fuck(x) cout<<#x<<"     "<<x<<endl;
    typedef pair<int,int> pii;
    const int maxn=1e6+10;
    int d[4][2]={1,0,-1,0,0,1,0,-1};
    //int lowbit(int x){return x&-x;}
    //void add(int x,int v){while(x<=n)bit[x]+=v,x+=lowbit(x);}
    //int sum(int x){int ans=0;while(x>=1) ans+=bit[x],x-=lowbit(x);return ans;}
    char t[maxn];
    string Manacher(string s) {
        // Insert '#'
        string t = "$#";
        for (int i = 0; i < s.size(); ++i) {
            t += s[i];
            t += "#";
        }
        // Process t
        vector<int> p(t.size(), 0);
        int mx = 0, id = 0, resLen = 0, resCenter = 0;
        for (int i = 1; i < t.size(); ++i) {
            p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;
            while (t[i + p[i]] == t[i - p[i]]) ++p[i];
            if (mx < i + p[i]) {
                mx = i + p[i];
                id = i;
            }
            if (resLen < p[i]) {
                resLen = p[i];
                resCenter = i;
            }
        }
        return s.substr((resCenter - resLen) / 2, resLen - 1);
    }
    
    int main(){
    
        while(scanf("%s",t)!=EOF)
        {
            cout<<Manacher(t).size()<<endl;
        }
        return 0;
    }
    

    马拉车学习博客连接: 
    https://www.cnblogs.com/grandyang/p/4475985.html 

  • 相关阅读:
    Parquet文件结构笔记
    parquet 简介
    Kubernetes 路由问题&网络问题
    postgresql:terminate hung query
    Python 动态加载并下载"梨视频"短视频
    Python 豆瓣mv爬取
    Ubuntu 硬盘分区只读,重新挂载为读写分区之后,文件依然创建出错
    Ubuntu 装机软件
    iTOP4412开发板相关内容
    linux driver ------ GPIO的驱动编写和调用
  • 原文地址:https://www.cnblogs.com/eason9906/p/11754727.html
Copyright © 2011-2022 走看看