zoukankan      html  css  js  c++  java
  • ___Manacher(线性回文子串处理算法)

    昨晚的bc做得好忧郁-----

    第一题改了好久好久好久----等改完发现比赛已经结束了(发现是枚举子集的位运算那儿写错了--)

    第二题是判断能否将一个字符串划分成三段回文串

    今天学了一点点  Manacher

    http://wenku.baidu.com/view/3031d2d3360cba1aa811da42.html

    模板大概是这样的--

     1 void Manacher(){
     2     for(int i = 1;i <= len;i++){
     3         t[2*i-1] = '#';
     4         t[2*i] = s[i];
     5     }
     6     t[0] = '?';t[len*2+1] = '#';
     7     t[2*len+2] = '';
     8     int tmax = 0,id = 0;
     9     len = len*2 + 1;
    10     for(int i = 1;i <= len;i++){
    11         if(tmax > i) p[i] = min(p[2*id-i],tmax-i);
    12         else p[i] = 1;
    13         while(t[i-p[i]] == t[i+p[i]]) p[i]++;
    14         if(i+p[i] > tmax){
    15             tmax = i+p[i];
    16             id = i;
    17         }
    18     }
    19 }
    View Code

    hdu 3068

    求最长回文串

     1 #include <cstdio>
     2 #include <ctime>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <cmath>
     6 #include <vector>
     7 #include <map>
     8 #include <set>
     9 #include <stack>
    10 #include <queue>
    11 #include <string>
    12 #include <iostream>
    13 #include <algorithm>
    14 using namespace std;
    15 
    16 #define getmid(l,r) ((l) + ((r) - (l)) / 2)
    17 #define MP(a,b) make_pair(a,b)
    18 #define PB push_back
    19 
    20 typedef long long ll;
    21 typedef pair<int,int> pii;
    22 const double eps = 1e-8;
    23 const int INF = (1 << 30) - 1;
    24 const int maxn = 2*110005;
    25 
    26 char s[maxn];
    27 char t[maxn];
    28 int p[maxn];
    29 
    30 void Manacher(){
    31     int len = strlen(s+1);
    32     for(int i = 1;i <= len;i++){
    33         t[2*i-1] = '#';
    34         t[2*i] = s[i];
    35     }
    36     t[0] = '?';
    37     t[2*len+1] = '#';
    38     t[2*len+2] = '';
    39     int tmax = 0,id = 0;
    40     int ans = 0;
    41     len = 2*len + 1;
    42     for(int i = 1;i <= len;i++){
    43         if(tmax > i) p[i] = min(p[2*id-i],tmax-i);
    44         else p[i] = 1;
    45         while(t[i-p[i]] == t[i+p[i]]) p[i]++;
    46         if(i+p[i] > tmax){
    47             tmax = i+p[i];
    48             id = i;
    49         }
    50         ans = max(ans,p[i]);
    51     }
    52     printf("%d
    ",ans-1);
    53 }
    54 
    55 int main(){
    56     while(scanf("%s",s+1) != EOF){
    57         Manacher();
    58     }
    59     return 0;
    60 }
    View Code

    hdu 5340

    先用一遍Manacher

    然后如果从1到这个位置是回文串的话,把这个位置加进L[]数组

    如果从这个位置到结尾是回文串的话,把这个位置加进R[]数组

    再枚举L,R,判断L---R这个区间是不是回文串

    判断方法就是看一下,这个区间的中点的p[i]能否覆盖这个中间部分---

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<vector>
     6 using namespace std;
     7 
     8 const int maxn = 40005;
     9 
    10 char s[maxn],t[maxn];
    11 int p[maxn],L[maxn],R[maxn];
    12 int len;
    13 
    14 void Manacher(){
    15     for(int i = 1;i <= len;i++){
    16         t[2*i-1] = '#';
    17         t[2*i] = s[i];
    18     }
    19     t[0] = '?';t[len*2+1] = '#';
    20     t[2*len+2] = '';
    21     int tmax = 0,id = 0;
    22     len = len*2 + 1;
    23     for(int i = 1;i <= len;i++){
    24         if(tmax > i) p[i] = min(p[2*id-i],tmax-i);
    25         else p[i] = 1;
    26         while(t[i-p[i]] == t[i+p[i]]) p[i]++;
    27         if(i+p[i] > tmax){
    28             tmax = i+p[i];
    29             id = i;
    30         }
    31     }
    32 }
    33 
    34 bool solve(){
    35     Manacher();
    36     int l = 0,r = 0;
    37     int length = strlen(s+1);
    38     for(int i = 2;i <= len-1;i++){
    39         if(i - p[i] == 0) L[l++] = i;
    40         if(i + p[i] == len+1) R[r++] = i;
    41     }
    42     
    43     for(int i = 0;i < l;i++){
    44         for(int j = r-1;j >= 0;j--){
    45         //    printf("R[%d] = %d  ",j,R[j]);
    46             int lb = L[i] + p[L[i]],ub = R[j] - p[R[j]];
    47             if(lb > ub) break;
    48             int mid = (lb + ub)/2;
    49          //   printf("lb = %d  ub = %d  mid = %d
    ",lb,ub,mid);
    50             if(p[mid] > mid - lb) return true;             
    51         }
    52     }
    53     return false;
    54 }
    55 
    56 int main(){
    57     int T;
    58     scanf("%d",&T);
    59     while(T--){
    60         memset(p,0,sizeof(p));
    61         scanf("%s",s+1);
    62         len = strlen(s+1);
    63         if(solve()) printf("Yes
    ");
    64         else printf("No
    ");
    65     }
    66     return 0;
    67 }
    View Code

    题解的暴力压位还是不会的说啊~~~

  • 相关阅读:
    strcpy的实现
    使用Highcharts生成柱状图
    使用Highcharts结合PHP与Mysql生成饼状图
    shopnc 学习笔记
    php中关于mysqli和mysql区别的一些知识点分析
    jquery捕获enter键 按enter键执行提交
    php在IE浏览器中保存SESSION
    ShopNC 商城系统开发经验分享第五篇: 缓存设计
    ShopNC 商城系统开发经验分享第二篇:ShopNC商城系统初步分析
    SHOPEX于SHOP++比较哪款更适合做二次开发,为什么?
  • 原文地址:https://www.cnblogs.com/wuyuewoniu/p/4696201.html
Copyright © 2011-2022 走看看