[Cpp]
Calculate the longest public return string of two strings, and output one string randomly.
# Include <cstdio>
# Include <cstring>
# Include <cstdlib>
# Include <algorithm>
Using namespace std;
# Define maxn10100
Int rad [MAXN];
Char s [MAXN];
Char r1 [MAXN/2], r [MAXN];
Int sa [MAXN];
Int wa [MAXN], wb [MAXN], wv [MAXN], ws [MAXN];
Int height [MAXN], rank [MAXN];
Int ans, start;
Inline bool cmp (int * r, int a, int B, int len ){
Return r [a] = r [B] & r [a + len] = r [B + len];
}
Void SA (int n, int m ){
Int I, j, p, * x = wa, * y = wb, * t;
For (I = 0; I <m; I ++)
Ws [I] = 0;
For (I = 0; I <n; I ++)
Ws [x [I] = r [I] ++;
For (I = 1; I <m; I ++)
Ws [I] + = ws [I-1];
For (I = n-1; I> = 0; I --)
Sa [-- ws [x [I] = I;
For (j = p = 1; p <n; j <= 1, m = p ){
For (p = 0, I = n-j; I <n; I ++)
Y [p ++] = I;
For (I = 0; I <n; I ++ ){
If (sa [I]> = j)
Y [p ++] = sa [I]-j;
}
For (I = 0; I <m; I ++)
Ws [I] = 0;
For (I = 0; I <n; I ++)
Ws [wv [I] = x [y [I] ++;
For (I = 1; I <m; I ++)
Ws [I] + = ws [I-1];
For (I = n-1; I> = 0; I --)
Sa [-- ws [wv [I] = y [I];
For (t = x, x = y, y = t, x [sa [0] = 0, p = I = 1; I <n; I ++)
X [sa [I] = cmp (y, sa [I-1], sa [I], j )? P-1: p ++;
}
}
Void Height (int n ){
Int I, j, k = 0;
For (I = 1; I <= n; I ++)
Rank [sa [I] = I;
For (I = 0; I <n; height [rank [I ++] = k)
For (k? K --: 0, j = sa [rank [I]-1]; r [I + k] = r [j + k]; k ++ );
}
Void Manacher (char str [], int n ){
Int I, mx = 0, id;
For (I = 1; I <n; I ++ ){
If (mx> I) rad [I] = min (rad [2 * id-I], mx-I );
Else rad [I] = 0;
For (; str [I + rad [I] = str [I-rad [I]; rad [I] ++)
;
Rad [I] --;
If (mx <rad [I] + I ){
Mx = rad [I] + I;
Id = I;
}
}
}
Int make_string (int mid ){
Strcpy (r, r1 );
R [mid] = '#';
Scanf ("% s", r + mid + 1 );
Return strlen (r );
}
Void cal_str (int from, int len ){
Int I;
S [0] = '$ ';
For (I = 0; I <len; I ++ ){
S [2 * I + 1] = '#';
S [2 * I + 2] = r1 [I + from];
}
S [2 * len + 1] = '#';
S [2 * len + 2] = '@';
Manacher (s, 2 * len + 2 );
Int t = 0;
For (I = 1; I <= 2 * len + 1; I ++ ){
If (rad [I]> ans ){
Ans = rad [I];
Start = from + t-rad [I]/2;
}
If (s [I]! = '#')
T ++;
}
}
Int main (){
Int n, mid;
Memset (height, 0, sizeof (height ));
Scanf ("% s", r1 );
Mid = strlen (r1 );
N = make_string (mid );
SA (n + 1,130 );
Height (n );
Ans = 0;
For (int I = 2; I <= n; I ++ ){
If (sa [I-1] <mid & sa [I]> mid)
Cal_str (sa [I-1], height [I]);
Else if (sa [I] <mid & sa [I-1]> mid)
Cal_str (sa [I], height [I]);
}
For (int I = 0; I <ans; I ++)
Printf ("% c", r1 [start + I]);
Printf ("\ n ");
}
Method 2: Perform manacher directly on two strings, then enumerate the positions on the two strings, and perform the following operations using the dp of n ^ 2.
[Cpp]
# Include <cstdio>
# Include <cstring>
# Include <cstdlib>
# Include <algorithm>
# Define maxn4010
Using namespace std;
Int rad1 [MAXN], rad2 [MAXN];
Char s1 [MAXN], s2 [MAXN], str1 [MAXN], str2 [MAXN];
Int ans, start;
Int dp [MAXN] [MAXN];
Void Manacher (int rad [], char str [], int n ){
Int I, mx = 0, id;
For (I = 1; I <n; I ++ ){
If (mx> I) rad [I] = min (rad [2 * id-I], mx-I );
Else rad [I] = 0;
For (; str [I + rad [I] = str [I-rad [I]; rad [I] ++)
;
Rad [I] --;
If (mx <rad [I] + I ){
Mx = rad [I] + I;
Id = I;
}
}
}
Void cal_str (char str [], char s [], int rad []) {
Int I, len;
Len = strlen (str );
S [0] = '$ ';
For (I = 0; I <len; I ++ ){
S [2 * I + 1] = '#';
S [2 * I + 2] = str [I];
}
S [2 * len + 1] = '#';
S [2 * len + 2] = '\ 0 ';
Manacher (rad, s, 2 * len + 2 );
}
Void sea (){
Int l1, l2, I, j, t;
L1 = strlen (s1 );
L2 = strlen (s2 );
Memset (dp, 0, sizeof (dp ));
T = 0;
For (I = 1; I <l1; I ++ ){
For (j = 1; j <l2; j ++ ){
If (s1 [I] = s2 [j])
Dp [I] [j] = dp [I-1] [J-1] + 1;
Int MIN = min (dp [I] [j]-1, min (rad1 [I], rad2 [j]);
If (MIN> ans ){
Ans = MIN;
Start = t-ans/2;
}
}
If (s1 [I]! = '#')
T ++;
}
}
Int main (){
Int n, I;
Scanf ("% s", str1 );
Cal_str (str1, s1, rad1 );
Scanf ("% s", str2 );
Cal_str (str2, s2, rad2 );
Ans = 0, start = 0;
Sea ();
For (I = 0; I <ans; I ++)
Printf ("% c", str1 [start + I]);
Printf ("\ n ");
}