zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    Noe4j启动警告
    SpringBoot
    MySQL数据库 java SQL语句区分大小写分析
    day24 模块的语法
    day23 re模块
    day22 常用模块02 序列化
    day21 常用模块01
    day20 面向对象06 MRO和C3算法
    day19 面向对象05 约束
    day18 面向对象04 反射
  • 原文地址:https://www.cnblogs.com/czhui666/p/13693913.html
Copyright © 2011-2022 走看看