CF126B Password

题目传送门

解题思路:

先跑一遍KMP,维护出不包括题目所给串(暂且称他文本串)本身的其他串中最大的最长公共前后缀(mm),然后找文本串的公共前后缀中小于mm最大的那一个(u),如果长度为0,说明没答案,如果不为0,则前mm个字符即为答案,感性证明一下,mm不为0说在中间有一部分与开头匹配,且长度1~mm都是可以找到匹配方案的,如果最后找到的u大于零,说明最后u位于最开头的u位可以匹配,而最开头的u位于中间有匹配方案,所以就满足了答案条件.

AC代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 
 4 using namespace std;
 5 
 6 string l,p;
 7 int kmp[1000001],j,mm;
 8 bool flag;
 9 
10 inline int max(int a,int b) {
11     if(a > b) return a;
12     return b;
13 }
14 
15 int main() {
16     cin >> p;
17     l = " " + p;
18     int n = l.length() - 1;
19     for(int i = 2;i <= n; i++) {
20         while(j != 0 && l[i] != l[j+1]) j = kmp[j];
21         if(l[i] == l[j+1]) j++;
22         kmp[i] = j;
23         if(i != n) mm = max(mm,kmp[i]);
24     }
25     int u = kmp[n];
26     while(u > mm) u = kmp[u];
27     if(u == 0) {
28         printf("Just a legend");
29         return 0;
30     }
31     for(int i = 1;i <= u; i++)
32         cout << l[i];
33     return 0;
34 }
原文地址:https://www.cnblogs.com/lipeiyi520/p/12364473.html