![4d4cbc8a14432a65793935a0ce5fd37e.png](https://i-blog.csdnimg.cn/blog_migrate/4648f111c399ee0838dde63c5b06187d.jpeg)
// 最长公共子序列(后缀自动机)
typedef struct state
{
int len, link;
map<char, int> next;
}state;
const int MAXLEN = 100000;
state st[MAXLEN * 2];
int sz, last;
void sa_init()
{
sz = last = 0;
st[0].len =0;
st[0].link = -1;
++sz;
for (int i = 0; i < MAXLEN * 2; ++i)
{
st[i].next.clear();
}
}
void sa_extend(char c)
{
int cur = sz++;
st[cur].len = st[last].len + 1;
int p;
for (p = last; p != -1 && !st[p].next.count(c); p = st[p].link)
{
st[p].next[c] = cur;
}
if (p == -1)
{
st[cur].link = 0;
}
else
{
int q = st[p].next[c];
if (st[p].len + 1 == st[q].len)
st[cur].link = q;
else
{
int clone = sz++;
st[clone].len = st[p].len + 1;
st[clone].next = st[q].next;
st[clone].link = st[q].link;
for (; p != -1 && st[p].next[c] == q; p = st[p].link)
st[p].next[c] = clone;
st[q].link = st[cur].link = clone;
}
}
last = cur;
}
string lcs(string s, string t)
{
sa_init();
for (int i = 0; i < (int)s.size(); ++i)
{
sa_extend(s[i]);
}
int v = 0, l = 0, best = 0, best_pos = 0;
for (int i = 0; i < (int)t.size(); ++i)
{
while (v && !st[v].next.count(t[i]))
{
v = st[v].link;
l = st[v].len;
}
if (st[v].next.count(t[i]))
{
v = st[v].next[t[i]];
++l;
}
if (l > best)
{
best = l;
best_pos = i;
}
}
return t.substr(best_pos - best + 1, best);
}
int main()
{
string s, t;
cin >> s >> t;
cout << lcs(s, t) << endl;
system("pause");
return 0;
}