P3435 [POI2006]OKR-Periods of Words KMP算法

P3435 [POI2006]OKR-Periods of Words

题目链接

​ KMP算法。

​ 一开始主要是题意没搞懂,搞懂了就好写了。题目大意就是:给定一个字符串,让你求这个字符串的每一个前驱的proper前驱的长度总和,proper前驱的意思就是某个字符串(x)的一个不为自己的前驱,复制两遍后拼接起来的字符串为(y),使(x)(y)的前驱。

(使用了洛谷 @Orion545dalao的图)

​ 图中黑色的是字符串(x),蓝色的就是我们要找的proper前驱。利用(next)数组的性质,我们可以使两段绿色的部分相同,这样当蓝色的部分复制两遍拼接起来后得到的字符串(y)(x)肯定是(y)的前驱。所以我们现在找到一个不为0的最小的(next)就好了,让(ans += len_x - next)

​ 注意要使用一个优化:(next[x])等于绿色部分长度。不然会TLE。

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 5;
int n, j, nxt[N];
long long ans;
char ch[N];

int main() {

    cin >> n; cin >> ch + 1;
    
    for(int i = 2;i <= n; i++) {
        while(j && ch[j + 1] != ch[i]) j = nxt[j];
        j += (ch[j + 1] == ch[i]); nxt[i] = j;
    }

    for(int i = 1;i <= n; i++) {
        j = i;
        while(nxt[j]) j = nxt[j];
        if(nxt[i]) nxt[i] = j; //优化
        ans += i - j;
    }

    printf("%lld", ans);

    return 0;
}
原文地址:https://www.cnblogs.com/czhui666/p/13693913.html