Meaning of the questions:
Given two strings a, b, seeking a string that is a substring of a and b,
Occurs only once and a, b, the minimum required length of the output string.
answer:
The suffix automaton into a string, and then click the recording frequency corresponding to each node appears substring
Then the string from the matching incentive b
Then judge for themselves
1 #include <set> 2 #include <map> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstring> 11 #include <iostream> 12 #include <algorithm> 13 #include <unordered_map> 14 15 #define pi acos(-1.0) 16 #define eps 1e-9 17 #define fi first 18 #define se second 19 #define rtl rt<<1 20 #define rtr rt<<1|1 21 #define bug printf("******\n") 22 #define mem(a, b) memset(a,b,sizeof(a)) 23 #define name2str(x) #x 24 #define fuck(x) cout<<#x" = "<<x<<endl 25 #define sfi(a) scanf("%d", &a) 26 #define sffi(a, b) scanf("%d %d", &a, &b) 27 #define sfffi(a, b, c) scanf("%d %d %d", &a, &b, &c) 28 #define sffffi(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d) 29 #define sfL(a) scanf("%lld", &a) 30 #define sffL(a, b) scanf("%lld %lld", &a, &b) 31 #define sfffL(a, b, c) scanf("%lld %lld %lld", &a, &b, &c) 32 #define sffffL(a, b, c, d) scanf("%lld %lld %lld %lld", &a, &b, &c, &d) 33 #define sfs(a) scanf("%s", a) 34 #define sffs(a, b) scanf("%s %s", a, b) 35 #define sfffs(a, b, c) scanf("%s %s %s", a, b, c) 36 #define sffffs(a, b, c, d) scanf("%s %s %s %s", a, b,c, d) 37 #define FIN freopen("../in.txt","r",stdin) 38 #define gcd(a, b) __gcd(a,b) 39 #define lowbit(x) x&-x 40 #define IO iOS::sync_with_stdio(false) 41 42 43 using namespace std; 44 typedef long long LL; 45 typedef unsigned long long ULL; 46 const ULL seed = 13331; 47 const LL INFLL = 0x3f3f3f3f3f3f3f3fLL; 48 const int maxm = 8e6 + 10; 49 const int INF = 0x3f3f3f3f; 50 const int mod = 1e9 + 7; 51 const int maxn = 250007; 52 char s[maxn]; 53 int Q; 54 55 struct Suffix_Automaton { 56 int last, tot, nxt[maxn << 1][26], fail[maxn << 1 ]; // number belongs longest prefix node is not added last before this character (the entire string) 57 is int len [MAXN << 1 ]; // longest substring length (the number of nodes = len substring len [FA [X]]) - [X] 58 int SA [MAXN << . 1 ], C [MAXN << . 1 ;] 59 int SZ [MAXN << . 1 ;] // number suffixes are linked, to facilitate the number of nodes required string 60 LL NUM [MAXN << . 1 ]; // this state, the number of sub-string 61 is LL Maxx [MAXN << . 1 ]; // length sub-string x largest number of occurrences of substrings The number 62 is LL SUM [MAXN << . 1 ]; //Since the string is formed behind the total number of the node 63 is LL subnum, sublen; // subnum represents a different number of strings, sublen different string length represents the total 64 int X-[MAXN << . 1 ], the Y [MAXN << . 1 ] ; // the Y represents ranked node x, x represents how many there are in front of the length 65 int Minn [MAXN << . 1 ], MX [MAXN << . 1 ]; // Minn [I] represents a plurality of strings suffix automaton node i longest common substring, mx [i] represents a single string of the longest common substring 66 void the init () { 67 TOT = Last = . 1 ; 68 Fail [ . 1 ] = len [ . 1 ] = 0 ; 69 for (int i = 0; i < 26; i++) nxt[1][i] = 0; 70 } 71 72 void extend(int c) { 73 int u = ++tot, v = last; 74 len[u] = len[v] + 1; 75 num[u] = 1; 76 for (; v && !nxt[v][c]; v = fail[v]) nxt[v][c] = u; 77 if (!v) fail[u] = 1, sz[1]++; 78 else if (len[nxt[v][c]] == len[v] + 1) fail[u] = nxt[v][c], sz[nxt[v][c]]++; 79 else { 80 int now = ++tot, cur = nxt[v][c]; 81 len[now] = len[v] + 1; 82 memcpy(nxt[now], nxt[cur], sizeof(nxt[cur])); 83 fail[now] = fail[cur]; 84 fail[cur] = fail[u] = now; 85 for (; v && nxt[v][c] == cur; v = fail[v]) nxt[v][c] = now; 86 sz[now] += 2; 87 } 88 Last = U; 89 // return len [Last] - len [Fail [Last]]; // add more a number of different sub-sub-string generated strings 90 } 91 is 92 void get_num () { // each node substring occurring number 93 for ( int I = . 1 ; I <= TOT; I ++) X-[len [I]] ++ ; 94 for ( int I = . 1 ; I <= TOT; I ++) X-[I ] X-+ = [I - . 1 ]; 95 for ( int I = . 1 ; I <= TOT; I ++) the Y [X-[len [I]] -] = I; 96 for ( int I = TOT; I> = . 1 ; i--) NUM [Fail [the Y [I]]] + = NUM [the Y [I]]; 97 } 98 99 void get_maxx ( int n-) { // length the number of sub x string occurs most often substrings 100 get_num (); 101 for ( int I = . 1 ; I <= TOT; I ++) Maxx [len [I]] = max (Maxx [len [I]] , NUM [I]); 102 } 103 104 void get_sum () { // total number string formed from the rear node 105 get_num (); 106 for ( intTOT = I; I> = . 1 ; i-- ) { 107 SUM [the Y [I]] = . 1 ; 108 for ( int J = 0 ; J <= 25 ; J ++ ) 109 SUM [the Y [I]] = + SUM [NXT [the Y [I]] [J]]; 110 } 111 } 112 113 void get_subnum () { // essentially different from the number of sub-strings 114 subnum = 0 ; 115 for ( int I = . 1 ; I < TOT =; I ++) subnum + = len [I] - len [Fail [I]]; 1 16 } 117 1 18 void get_sublen () { // essentially different from the substring of the total length of 119 sublen = 0 ; 120 for ( int I = . 1 ; I <= TOT; I ++) sublen + = 1LL * (len [I] + len [Fail [I]] + . 1 ) * (len [I] - len [Fail [I]]) / 2 ; 121 } 122 123 void get_sa () { // Get sa array 124 for ( int I = . 1 ; I <= TOT; I ++) C [len [I]] ++ ; 125 for ( int I =. 1 ; I <= TOT; I ++) C [I] + C = [I - . 1 ]; 126 for ( int I = TOT; I> = . 1 ; i--) SA [C [len [I]] - ] = I; 127 } 128 129 int cntnum [MAXN << . 1 ]; 130. 131 is void match () { // plurality of longest common substring of string 132 MEM (cntnum, 0 ); 133 int n-= strlen (S ), P = . 1 , ANS = INF; 134 for ( int I = 0 ; I <n-; I ++ ) { 135 int c = s[i] - 'a'; 136 if (nxt[p][c]) p = nxt[p][c]; 137 else { 138 for (; p && !nxt[p][c]; p = fail[p]); 139 if (!p) p = 1; 140 else p = nxt[p][c]; 141 } 142 cntnum[p]++; 143 } 144 for (int i = tot; i; i--) cntnum[fail[Y[i]]] += cntnum[Y[i]]; 145 for (int i = 2 ; I <= TOT; I ++ ) 146 IF (NUM [I] == . 1 && cntnum [I] == . 1 ) ANS = min (ANS, len [Fail [I]] + . 1 ); 147 IF (ANS = INF =) the printf ( " -1 \ n- " ); 148 the else the printf ( " % D \ n- " , ANS); 149 } 150 151 void get_kth ( int K) { // determine the K sub-sequence string dictionary 152 int POS = . 1 , CNT; 153 String S = "" ; 154 while (k) { 155 for (int i = 0; i <= 25; i++) { 156 if (nxt[pos][i] && k) { 157 cnt = nxt[pos][i]; 158 if (sum[cnt] < k) k -= sum[cnt]; 159 else { 160 k--; 161 pos = cnt; 162 s += (char) (i + 'a'); 163 break; 164 } 165 } 166 } 167 } 168 cout << s << endl; 169 } 170 171 } sam; 172 173 int main() { 174 #ifndef ONLINE_JUDGE 175 FIN; 176 #endif 177 sam.init(); 178 sfs(s + 1); 179 int n = strlen(s + 1); 180 for (int i = 1; i <= n; i++) sam.extend((s[i] - 'a')); 181 sfs(s); 182 sam.get_num(); 183 sam.match(); 184 #ifndef ONLINE_JUDGE 185 cout << "Totle Time : " << (double) clock() / CLOCKS_PER_SEC << "s" << endl; 186 #endif 187 return 0; 188 }