• 【YBTOJ】【kmp】字符串题


    字符串题

    一个串 (T)(S) 的循环节,当且仅当存在正整数 (k) ,使得 (S)(T) 重复 (k) 次形成的字符串的前缀,比如 abcdabcdabcdab 的循环节。

    已知 (S) 是一个长度为 (n) 的仅由小写字符构成的字符串, (S) 的长度为 (i) 的前缀的最短循环节的长度 (pre_i)

    告诉你 (n) 以及 (pre_{1cdots n}) ,请找到一个长度为 (n) 的小写字符串 ,使得 (S) 能对应上 (pre) 数组。



    题解

    结论:对于一个字符串,其最短循环节为 (n-fail_n) .

    那么, (i-pre_i=fail_i) .

    以下分为两种情况考虑:

    1. (fail_i eq0)
    • 此时 (fail_i) 表示 (1cdots i) 中前缀与后缀相等部分,则 (a_iequiv a_{fail_i}).
    1. (fail_i=0)
    • 我们考虑 kmp 的过程:
      • while(j && b[j+1] != b[i]) j = fail[j];
      • j += b[j+1] == b[i];
    • 如果 (fail_i=0),那么意味着随着 (fail) 向前跳动,(b[j+1] eq b[i]) 恒成立。
    • 所以,在所有 (b_{j+1}) 未出现过的字符中,找到字典序最小的即可。

    代码

    #include <bits/stdc++.h>
    #define fo(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
    const int INF = 0x3f3f3f3f,N = 1e5+5,mod = 1e9+7;
    typedef long long ll;
    typedef unsigned long long ull;
    inline ll read(){
    	ll ret=0;char ch=' ',c=getchar();
    	while(!(c>='0'&&c<='9'))ch=c,c=getchar();
    	while(c>='0'&&c<='9')ret=(ret<<1)+(ret<<3)+c-'0',c=getchar();
    	return ch=='-'?-ret:ret;
    }
    int n;
    int pre[N],fail[N];
    char a[N];
    bool vis[300];
    signed main(){
    	n = read();
    	for(int i = 1 ; i <= n ; i ++)
    		pre[i] = read(),
    		fail[i] = i - pre[i];
    //	for(int i = 1 ; i <= n ; i ++)printf("fail[%d] = %d
    ",i,fail[i]);
    	a[1] = 'a';
    	fail[0] = -1;
    	for(int i = 2 ; i <= n ; i ++){
    		if(fail[i])
    			a[i] = a[fail[i]];
    		else{
    			int j = fail[i-1];
    			while(~j) vis[(int)a[j+1]] = 1 , j = fail[j];
    			for(int k = 'a' ; k <= 'z' ; k ++)
    				if(!vis[k]) {a[i] = k;break;} 
    				else vis[k] = 0;
    		}
    	}
    	puts(a+1);
    	return 0;
    }
    
  • 相关阅读:
    002-Linux下防火墙相关命令操作
    001-网卡配置
    vs2012中自带IIS如何让其他电脑访问
    001-Mono for android在vs2012中发布设置
    小知识:utf-8和utf8mb4字符集
    Maven 模块化开发
    JUnit 单元测试
    解决8080端口占用问题
    (三)Tomcat服务器 -------JavaWeb的学习之路
    (一)走进JavaWeb的世界 -------JavaWeb的学习之路
  • 原文地址:https://www.cnblogs.com/Shinomiya/p/15308641.html
Copyright © 2020-2023  润新知