• [POI2006]OKR-Periods of Words


    Description

    Luogu3435
    对一个字符串(A),定义其周期(Q)为,(Q)(A)的前缀((Q!=A))且(A)(QQ)的前缀((A)可以等于(QQ))。求一个字符串的所有前缀的最长周期的长度之和。

    Solution

    首先观察周期的定义,可以发现,一旦该字符串有一个前缀等于该字符串的一个后缀,那么这个字符串就是有周期的,与前后缀有关的那就是KMP了。而要求周期最长,就是要求该前缀最短,转化问题之后就可以用KMP解决了。但是,sb的我竟然在KMP的过程中xjb乱跳,直接就跳到最短的了,可是这样会挂啊!考虑这样的一个字符串abacabac,如果在KMP里就处理答案的话就会影响next数组的求解,所以要在KMP之后求答案。

    哦对了,求答案的时候可以记忆化一下。

    Code

    #include <cstdio>
    
    typedef long long LL;
    const int N = 1e6 + 10;
    
    char s[N];
    int nxt[N]; 
    LL ans;
    int n;
    
    int main() {
    	scanf("%d", &n);
    	scanf("%s", s+1);
    	nxt[0] = -1;
    	for (int i = 1; i <= n; ++i) {
    		int t = nxt[i-1];
    		while (t != -1 && s[t+1] != s[i]) t = nxt[t];
    /*		这里不能有这句话啊!!!!!!!!!!!!!!! 
    		if (t != -1) while (nxt[t] != -1 && s[nxt[t] + 1] == s[i]) t = nxt[t];
    */		nxt[i] = t + 1;		
    	}
    	for (int i = 1; i <= n; ++i) {
    		int t = nxt[i];
    		while (nxt[t] > 0) t = nxt[t];
    		if (nxt[i]) nxt[i] = t; // 记忆化一下 
    		if (t) ans += i - t; 
    	}
    	printf("%lld
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    Node入门
    Java try-catch、throw和throws的几点想法
    SpringMVC的四种HandlerMapping
    枚举
    MyBatis表和实体关联
    MyBatis xml和dao层接口组合使用
    Spring Task 定时器
    (转)Spring定时任务的几种实现
    Struts2+Spring发送邮件
    Struts2文件上传
  • 原文地址:https://www.cnblogs.com/wyxwyx/p/poi2006okrp.html
Copyright © 2020-2023  润新知