zoukankan      html  css  js  c++  java
  • BZOJ 2565 最长双回文串 (Manacher)

    2565: 最长双回文串

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 2658  Solved: 1346
    [Submit][Status][Discuss]

    Description

    顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同)。
    输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(|X|,|Y|≥1)且X和Y都是回文串。

    Input

    一行由小写英文字母组成的字符串S

    Output

    一行一个整数,表示最长双回文子串的长度。

    Sample Input

    baacaabbacabb

    Sample Output

    12

    HINT

    样例说明

    从第二个字符开始的字符串aacaabbacabb可分为aacaa与bbacabb两部分,且两者都是回文串。

    对于100%的数据,2≤|S|≤10^5


    2015.4.25新加数据一组

    Source

    析:首先先用Manacher算法处理出来,然后再求以 i 为开头和结尾的的最长回文串长度lx[i],rx[i],然后再求lx[i] + rx[i] 最大值即可。
    代码如下:
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <cmath>
    #include <iostream>
    #include <cstring>
    #include <set>
    #include <queue>
    #include <algorithm>
    #include <vector>
    #include <map>
    #include <cctype>
    #include <cmath>
    #include <stack>
    #include <sstream>
    #include <list>
    #include <assert.h>
    #include <bitset>
    #define debug() puts("++++");
    #define gcd(a, b) __gcd(a, b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    #define pb push_back
    #define sqr(x) ((x)*(x))
    #define ms(a,b) memset(a, b, sizeof a)
    #define sz size()
    #define pu push_up
    #define pd push_down
    #define cl clear()
    #define all 1,n,1
    #define FOR(i,x,n)  for(int i = (x); i < (n); ++i)
    #define freopenr freopen("in.txt", "r", stdin)
    #define freopenw freopen("out.txt", "w", stdout)
    using namespace std;
    
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int, int> P;
    const int INF = 0x3f3f3f3f;
    const double inf = 1e20;
    const double PI = acos(-1.0);
    const double eps = 1e-4;
    const int maxn = 1e5 + 10;
    const int maxm = 2e5 + 10;
    const int mod = 1e9 + 7;
    const int dr[] = {-1, 0, 1, 0};
    const int dc[] = {0, -1, 0, 1};
    const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
    int n, m;
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    inline bool is_in(int r, int c) {
      return r >= 0 && r < n && c >= 0 && c < m;
    }
    
    char s[maxn];
    char ma[maxn<<1];
    int len[maxn<<1];
    int lx[maxn<<1], rx[maxn<<1];
    
    void manacher(int n){
      int l = 0;
      ma[l++] = '$';
      ma[l++] = '#';
      for(int i = 0; i < n; ++i)  ma[l++] = s[i], ma[l++] = '#';
      ma[l] = 0;
      int mx = 0, id = 0;
      for(int i = 0; i < l; ++i){
        len[i] = mx > i ? min(len[2*id-i], mx-i) : 1;
        while(ma[i+len[i]] == ma[i-len[i]])  ++len[i];
        if(i + len[i] > mx){
          mx = i + len[i];  id = i;
        }
        lx[i-len[i]+1] = max(lx[i-len[i]+1], len[i]-1);
        rx[i+len[i]-1] = max(rx[i+len[i]-1], len[i]-1);
      }
      for(int i = 1; i < l; ++i)  lx[i] = max(lx[i], lx[i-1] - 1);
      for(int i = l-2; i >= 0; --i)  rx[i] = max(rx[i], rx[i+1] - 1);
    }
    
    int main(){
      scanf("%s", s);
      n = strlen(s);
      manacher(n);
      int ans = 0;
      for(int i = 0; i < (n<<1|1); ++i)  ans = max(ans, lx[i] + rx[i]);
      printf("%d
    ", ans);
      return 0;
    }
    

      

  • 相关阅读:
    Delphi XE5 android 蓝牙通讯传输
    Delphi XE5 android toast
    Delphi XE5 android openurl(转)
    Delphi XE5 如何设计并使用FireMonkeyStyle(转)
    Delphi XE5 android 捕获几个事件
    Delphi XE5 android listview
    Delphi XE5 android 黑屏的临时解决办法
    Delphi XE5 android popumenu
    Delphi XE5 android 获取网络状态
    Delphi XE5 android 获取电池电量
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/7857446.html
Copyright © 2011-2022 走看看