kuangbin专题16H(next数组)
Posted ygeloutingyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kuangbin专题16H(next数组)相关的知识,希望对你有一定的参考价值。
题目链接: https://vjudge.net/contest/70325#problem/H
题意: 输入字符串 str, 求 str 子串中既是 str 前缀又是 str 后缀的的字符串长度, 按照升序输出.
思路: 先求个 next 数组, next[i] 为以 i - 1(字符串下标从0开始) 字符为后缀的字符串与以第一个字符为前缀的字符串的最大匹配长度.
首先 str 本身是满足条件的. 然后再不断用 next[len] 迭代 len 即可. len 的初始值为 str 的长度. 由 next 的性质可以知道以 next[len] - 1 为后缀的字符串会和以 len - 1 为后缀的字符串重合, 那么所有迭代到的子串都会和以 str 最后一个字符为后缀的字符串重合. (可以参考下面的图) 那么现在前后缀条件都满足啦.
图是从 http://www.cnblogs.com/dongsheng/archive/2012/08/13/2636261.html 偷过来的....
代码:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 using namespace std; 5 6 const int MAXN = 4e5 + 10; 7 int nxt[MAXN], vis[MAXN], len; 8 char str[MAXN]; 9 10 void get_nxt(void){ 11 memset(nxt, 0, sizeof(nxt)); 12 int i = 0, j = -1; 13 nxt[0] = -1; 14 while(i < len){ 15 if(j == -1 || str[i] == str[j]) nxt[++i] = ++j; 16 else j = nxt[j]; 17 } 18 } 19 20 int main(void){ 21 while(~scanf("%s", str)){ 22 len = strlen(str); 23 int cnt = 0; 24 get_nxt(); 25 vis[cnt++] = len; 26 while(nxt[len] > 0){ 27 len = nxt[len]; 28 vis[cnt++] = len; 29 } 30 for(int i = cnt - 1; i >= 0; i--){ 31 printf("%d", vis[i]); 32 if(i) printf(" "); 33 } 34 puts(""); 35 } 36 return 0; 37 }
以上是关于kuangbin专题16H(next数组)的主要内容,如果未能解决你的问题,请参考以下文章
算法系列学习线段树vs树状数组 单点修改,区间查询 [kuangbin带你飞]专题七 线段树 A - 敌兵布阵