首页 > 其他分享 >codeforces 126B B. Password(kmp+dp)

codeforces 126B B. Password(kmp+dp)

时间:2023-04-23 21:37:58浏览次数:49  
标签:子串 include 前缀 后缀 MAX codeforces next 126B Password


题目链接:

codeforces 126B


题目大意:

给出一个字符串,找出一个子串既是它的前缀,也是它的后缀,还是一个非后缀也非前缀的子串。


题目分析:

  • 本来挺简单的一个题,最开始想复杂了,还用了后缀数组,醉了。
  • 这个题主要用的是kmp的next数组,首先我们要了解next数组的定义,next[i]表示以i为末尾的子串的后缀与能够匹配的整个串的最长的前缀。
  • 然后我们可以知道后缀与前缀的最长相同的长度,现在是满足后缀和前缀的最长子串的情况。
  • 然后我们利用hash除了以最后一个字符结尾的情况所有的与前缀匹配的长度。
  • 最后我们利用next数组的性质,如果当前的匹配的长度在hash表中找不到,那么证明不存在非前缀与非后缀的子串符合条件,那么x=next[x],也就是跳转到当前位置失配的重新匹配的位置(免去重复匹配的部分),也就是小于当前情况的最大的子串的后缀和前缀匹配的情况,然后再查hash表。知道找到答案为止,找不到答案证明不存在解。

AC代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define MAX 1000007

using namespace std;

char s[MAX];
int next[MAX];
int hash[MAX];

void kmp ( int n )
{
    memset ( next , 0 , sizeof ( next ) );
    for ( int i = 2 ; i <= n ; i++ )
    {
        int k = next[i-1];
        while ( k && s[k+1] != s[i] ) k = next[k];
        if ( s[k+1] == s[i] ) next[i]=k+1;
    }
}

int main ( )
{
    while ( ~scanf ( "%s" , s+1 ) )
    {
        int n = strlen ( s+1 );
        kmp ( n );
        memset ( hash , 0  , sizeof ( hash ) );
        for ( int i = 2; i < n ; i++ )
            hash[next[i]] = 1;
        int x = next[n];
        while ( !hash[x] && x ) x = next[x];
        if ( !x ) printf ( "Just a legend" );
        else for ( int i = 1 ; i <= x ; i++ )
            printf ( "%c" , s[i] );
        puts ( "" );
    }

}


标签:子串,include,前缀,后缀,MAX,codeforces,next,126B,Password
From: https://blog.51cto.com/u_7936627/6218742

相关文章

  • codeforces 118D D. Caesar's Legions(dp)
    题目链接:codeforces118D题目大意:给出n1个1,n2个2,给出k1和k2代表连续的1和2的最大长度,问能够构造的合法的不同串的数量。题目分析:能够递推,所以想到能够利用dp做。首先我们定义状态,dp[i][j][k][2]代表以1或2结尾,结尾相同的元素的数量为k,1的总数是j的当前序列长度为i的串的数量。首先......
  • codeforces 264B B. Good Sequences(dp+数论)
    题目链接:codeforces264B题目大意:给出n个数,利用这n个数构造一个好的序列,好的序列是单调增的,而且序列中相邻的两个元素都不互质,问最长的好序列的长度是多少。题目分析:首先我们定义状态dp[i]表示当前的数进行构造的序列末尾的数的质因数包含i的时候的最长的情况。然后我们从小到大枚......
  • codeforces 159D D. Palindrome pairs( manacher+dp )
    题目链接:codeforces159D题目大意:给出一个字符出,求取这个字符串中互相不覆盖的两个回文子串的对数。题目分析:首先能够用manacher模板,因为这个算法处理的字符串的长度式奇数,所以我们首先将原字符串拓展,也就是用一个没有出现过的子串填充到每两个字符之间,首位也要添加,这样处理后得到......
  • codeforces 359B B. Permutation(简单构造)
    题目链接:codeforces359B题目大意:给出n和k,要求构造一个长度为2*n的排列,满足如下的式子:∑i=1n|a2∗i−1−a2∗i|−|∑i=1na2∗i−1−a2∗i|=2∗k题目分析:首先最终构造的2*k一定是小于n的偶数,如果我们直接放入自然数的排列,结果是0,我们将2*i-1和2*i分为一组,每次调换组内位置(每组只能......
  • codeforces 505B B. Mr. Kitayuta's Colorful Graph(bfs)
    题目链接:codeforces505B题目大意:给出一个有向图,边有不同的颜色,任意给出查询,查询两点能够只通过一种颜色连通的颜色的种类数。题目分析:根据不同颜色建边,bfs即可,队列维护可用的点。AC代码:#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<alg......
  • codeforces 332B B. Maximum Absurdity(rmq)
    题目链接:codeforces332B题目大意:给出一个序列,让找出不互相覆盖的两个长度为k的段,问在两个段的权值和最大的情况下,按照左边段的左端点排序,右边段的左端点作为第二关键字排序,得到的第一个答案。题目分析:很水的数据结构的题目,我们只需要先利用前缀和预处理出所有长度为k的段的总权值......
  • codeforces 234C C. Weather(枚举+前缀后缀预处理)
    题目链接:codeforces234C题目大意:给出一个序列,问最少修改多少个元素,能保证前半截全是负数,后半截全是正数。题目分析:预处理出前缀中大于等于0的数的个数和后缀中小于等于0的数的个数。枚举每一个位置,判断以当前位置为分界点时需要修改的元素的个数。AC代码:#include<iostream>#inc......
  • codeforces 172B B. Pseudorandom Sequence Period(暴力)
    题目链接:codeforces172B题目大意:给出生成元,和递推式,求一个有限群元素的个数题目分析:暴力求取循环节即可,因为元素个数不会超过mod的大小,所以暴力法复杂度仅仅是O(105)AC代码:#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cstdio>#de......
  • codeforces 368B B. Sereja and Suffixes(树状数组)
    题目链接:codeforces368B题目大意:给出一个长度为n的序列a,给出m个查询l,对于每个查询输出[l,n]的区间内不同数的个数。题目分析:将查询按照l的大小排序,从大到小的遍历,每次将>=当前l的位置的a[i]全部加入树状数组,树状数组记录每个数是否出现过。每次结果就是查询树状数组的总和,要保证......
  • codeforces 414B B. Mashmokh and ACM(dp)
    题目链接:codeforces414B题目大意:定义一个序列,前一项能够整除后一项,给定这个序列中数的取值范围和序列的长度,问有多少种构造方法。题目分析:我们定义状态dp[i][j]为前i项已经确定且第i项为j的方案数。转移方程dp[i][j]=∑k|jdp[i−1][k]复杂度O(n⋅k)AC代码:#include<iostream>......