zoukankan      html  css  js  c++  java
  • 回文子串的个数

    # 题意

    给定一个字符串,求字符串中有多少个回文子串
    单独一个字符也是一个回文串

    # 题解
    manacher,从1开始扫描整个回文半径数组,以每个点为中心的
    回文串的个数为 hw[i]/2,即除去分隔符的真实回文半径
    #1#2#3#3#2#1#

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=200010;
     4 char a[maxn],s[maxn<<1];
     5 int l[maxn<<1],r[maxn<<1];
     6 int n,hw[maxn],ans;
     7 // hw/2 即以 i 为中心的回文子串的个数
     8 // hw[ i ]-1即以 i 为中心的回文串的长度
     9 //在所有字符的前后 共插入n+1 个 '#'
    10 inline void change() {
    11     s[0]='~',s[1]='#';//边界
    12     for(int i=0; i<n; i++) {
    13         s[i*2+2]=a[i];
    14         s[i*2+3]='#';
    15     }
    16     n=n*2+2;
    17     s[n]='@';// 设置边界,两个边界不同
    18 }
    19 inline void manacher( ) {
    20     int maxright=0 , mid;
    21     for(int i = 1; i < n; i ++) {//枚举1...2n-1
    22         if(i < maxright)
    23             hw[i] = min ( hw[(mid << 1) - i ]  , hw [mid] + mid - i );
    24             // hw[(mid<<1)-i]即i关于mid对称的点. hw[mid] +mid-i,为当前到最长回文串终点的距离,特判定对称的点越界
    25         else
    26             hw[i] = 1;//hw[i]表示i点能够扩展出的回文半径
    27         while( s[i + hw[i]] == s[i - hw[i]] )//s[]存储字符串
    28             ++ hw[i];
    29         if(hw[i] + i > maxright) {
    30             maxright = hw[i] + i - 1;
    31             mid = i;
    32         }
    33     }
    34 }
    35 int main(){
    36     cin>>a;
    37     n=strlen(a);
    38     change();
    39     manacher();
    40     int ans=0;
    41     for(int i=0;i<n;i++)
    42         ans+=hw[i]/2;
    43     cout<<ans;
    44 }

     

     

  • 相关阅读:
    解释器模式
    命令模式
    责任链模式
    代理模式
    享元模式
    外观模式
    装饰器模式
    组合模式
    过滤器模式
    js广告浮动
  • 原文地址:https://www.cnblogs.com/hhyx/p/12528839.html
Copyright © 2011-2022 走看看