O(n)的复杂度求回文串:Manacher算法

定义一个回文值,字符串S是K重回文串,当且仅当S是回文串,且其长度为⌊N/2⌋的前缀和长度为⌊N/2⌋的后缀是K−1重回文串

现在给一个2*10^6长度的字符串,求其每个前缀的最大回文值之和。

设dp[i]为长度为i的前缀的最大回文值。

当长度为i的前缀的字符串是回文串的时候,有:dp[i]=dp[i/2]+1

若不是回文串 dp[i]=0

接下来就是怎么样快速的判断回文串了,推荐算法Manacher算法。

Manacher算法先对字符串进行修改 如 aba -> $#a#b#a#

那么该怎么用DP求?

显然一下几点是满足的:

如果某个前缀是回文串,该前缀的末端一定是字符#,(因为第一个符号是#)

故对于不是字符#的位置,它的dp值一定为0

如果最大延伸数组p[i]=i,即向左正好延伸到最左边,那么1~p[i]+i-1一定是一个回文前缀

若第i位是#号 : dp[mx]=dp[i]  其中mx=p[i]+i-1

对于不是#的情况 : dp[mx]=dp[i-1] 其中mx=p[i]+i-1

  1. #include<bits/stdc++.h>
  2. #define eps 1e-9
  3. #define FOR(i,j,k) for(int i=j;i<=k;i++)
  4. #define MAXN 4000005
  5. #define MAXM 40005
  6. #define INF 0x3fffffff
  7. #define PB push_back
  8. #define MP make_pair
  9. #define X first
  10. #define Y second
  11. #define lc (k<<1)
  12. #define rc ((k<<1)1)
  13. using namespace std;
  14. typedef long long LL;
  15. int i,j,k,n,m,x,y,T,ans,big,cas,num,len;
  16. bool flag;
  17.  
  18. int p[MAXN],dp[MAXN];
  19. char str[MAXN],s[MAXN];
  20.  
  21. void kp()
  22. {
  23. int i;
  24. int mx = ;
  25. int id;
  26. for(i=n; str[i]!=; i++)//清除n后边多余的部分
  27. str[i] = ; //没有这一句有问题。。就过不了ural1297,比如数据:ababa aba
  28. for(i=; i<n; i++)
  29. {
  30. if( mx > i )
  31. p[i] = min( p[*id-i], p[id]+id-i );
  32. //因为是从左往右扫描的这里i>id, 2*id-i是i关于id的对称点,该对称点在id的左端
  33. //p[id]+id是描述中的mx,即id向右延伸的端点位置
  34. //显然向右延伸是可能超出mx的,所以要有下边的for循环
  35. else
  36. p[i] = ;
  37. for(; str[i+p[i]] == str[i-p[i]]; p[i]++);
  38.  
  39. if( p[i] + i > mx )//更新mx与id,因为mx是向右延伸的最大长度,所以实时更新
  40. {
  41. mx = p[i] + i;
  42. id = i;
  43. }
  44. }
  45. }
  46.  
  47. void init()//处理字符串
  48. {
  49. int i, j, k;
  50. str[] = '$';
  51. str[] = '#';
  52. for(i=; i<n; i++)
  53. {
  54. str[i*+] = s[i];
  55. str[i*+] = '#';
  56. }
  57. n = n*+;
  58. s[n] = ;
  59. }
  60.  
  61. int main()
  62. {
  63. scanf("%s",s);
  64. n=strlen(s);
  65. init();
  66. kp();
  67. for (i=;i<n;i++)
  68. {
  69. if (p[i]==i)
  70. {
  71. int mx=p[i]+i-;
  72. if (str[i]!='#')
  73. {
  74. dp[mx]=max(dp[mx],dp[i-]+);
  75. }else
  76. dp[mx]=max(dp[mx],dp[i]+);
  77. }
  78. }
  79. int sum=;
  80. for (i=;i<n;i++) sum+=dp[i];
  81. printf("%d\n",sum);
  82. return ;
  83. }

2015 UESTC Training for Search Algorithm & String - M - Palindromic String【Manacher回文串】的更多相关文章

  1. UESTC_Palindromic String 2015 UESTC Training for Search Algorithm & String<Problem M>

    M - Palindromic String Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 128000/128000KB (Java ...

  2. UESTC_韩爷的梦 2015 UESTC Training for Search Algorithm & String<Problem N>

    N - 韩爷的梦 Time Limit: 200/100MS (Java/Others)     Memory Limit: 1300/1300KB (Java/Others) Submit Stat ...

  3. UESTC_Ferris Wheel String 2015 UESTC Training for Search Algorithm & String<Problem L>

    L - Ferris Wheel String Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 43000/43000KB (Java/ ...

  4. UESTC_秋实大哥の恋爱物语 2015 UESTC Training for Search Algorithm & String<Problem K>

    K - 秋实大哥の恋爱物语 Time Limit: 5000/2000MS (Java/Others)     Memory Limit: 32000/32000KB (Java/Others) Su ...

  5. UESTC_Eight Puzzle 2015 UESTC Training for Search Algorithm & String<Problem F>

    F - Eight Puzzle Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) ...

  6. UESTC_吴队长征婚 2015 UESTC Training for Search Algorithm & String<Problem E>

    E - 吴队长征婚 Time Limit: 10000/4000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  7. UESTC_基爷的中位数 2015 UESTC Training for Search Algorithm & String<Problem D>

    D - 基爷的中位数 Time Limit: 5000/3000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  8. UESTC_基爷与加法等式 2015 UESTC Training for Search Algorithm & String<Problem C>

    C - 基爷与加法等式 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Subm ...

  9. UESTC_邱老师降临小行星 2015 UESTC Training for Search Algorithm & String<Problem B>

    B - 邱老师降临小行星 Time Limit: 10000/5000MS (Java/Others)     Memory Limit: 65536/65535KB (Java/Others) Su ...

随机推荐

  1. jquery中的ajax方法详解

    定义和用法ajax() 方法通过 HTTP 请求加载远程数据.该方法是 jQuery 底层 AJAX 实现.简单易用的高层实现见 $.get, $.post 等.$.ajax() 返回其创建的 XML ...

  2. yii 验证用户名是否存在 array("name","unique",'message'=>'用户名已经存在'),

    //验证用户名是否存在                     array("name","unique",'message'=>'用户名已经存在'),

  3. STM32学习笔记——USART串口(向原子哥和火哥学习)

    一.USART简介 通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换.USART利用分数波特率发生器提供宽范围的波特率选择. S ...

  4. [BZOJ 1816] [Cqoi2010] 扑克牌 【二分答案】

    题目链接:BZOJ - 1816 题目分析 答案具有可以二分的性质,所以可以二分答案. 验证一个答案 x 是否可行,就累加一下各种牌相对于 x 还缺少的量,如果总和超过了 x 或 m ,就不可行. 因 ...

  5. 汉字转拼音的Java类库:JPinyin

    JPinyin是一个汉字转拼音的Java开源类库,在PinYin4j的功能基础上做了一些改进. [JPinyin主要特性]1.准确.完善的字库:Unicode编码从4E00-9FA5范围及3007(〇 ...

  6. 同一张表不同SESSION相互持有对方记录引发的死锁

    锁产生的原因:如果有两个会话,每个会话都持有另一个会话想要的资源,此时就会发生死锁. 同一张表不同SESSION持有不同记录 SQL> create table t1(id int); Tabl ...

  7. mysql 安装补充

    1:假如下载的文件名为:mysql-5.0.45.tar.gz 2:假如copy到 /usr/local下 3:groupadd mysql #添加mysql组 4:useradd -g mysql ...

  8. sublime每次打开时都提示升级,怎么取消这个弹出框?

    答案其实很简单,设置如下: 进入Preferences -> Settings-User ,添加 "update_check": false 重启Sublime. 发现了什么 ...

  9. Curling 2.0(dfs)

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8795   Accepted: 3692 Description On Pl ...

  10. 【离线】【深搜】【树】Codeforces 707D Persistent Bookcase

    题目链接: http://codeforces.com/problemset/problem/707/D 题目大意: 一个N*M的书架,支持4种操作 1.把(x,y)变为有书. 2.把(x,y)变为没 ...