Title Description:
There are A, B two sequences, the number of elements in the sequence
is n,m;Each element in the sequence are different and less than 100000.
Calculate the length of the longest common subsequence of A and B.
Input Description:
The input has multicases.Each test case consists of three lines;
The first line consist two integers n, m (1 < = n, m < = 100000);
The second line with n integers, expressed sequence A;
The third line with m integers, expressed sequence B;
Output description:
For each set of test cases, output the length of the longest common
subsequence of A and B, in a single line.
Sample input:
5 4 1 2 6 5 4 1 3 5 4
Sample output:
3
thinking
The idea is simple: give two lengths, then give two strings, let's find the length of lcs.
But because the data is too large, the ordinary O(n2)O(n2) approach is certainly not feasible. We need to consider a faster approach. Convert the LCS problem into the LIS problem, and then use the LIS nlogn solution to find the answer.
The idea is that, first of all, we assume that there are two strings, a and b, for example:
a | 1 | 2 | 3 | 5 | 4 |
---|---|---|---|---|---|
b | 5 | 4 | 3 | 2 | 1 |
subscript | 1 | 2 | 3 | 4 | 5 |
We find the subscripts of each number in b string in a string.
5 appears at 4, 4 at 5, 3 at 3, 2 at 2, 1 at 1, and a new string is formed.
4 5 3 2 1
Then the LIS length of the newly generated string is the answer.
Code
#include <cstdio>
#include <cstring>
#include <cctype>
#include <stdlib.h>
#include <string>
#include <map>
#include <iostream>
#include <sstream>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
#include <list>
using namespace std;
#define mem(a, b) memset(a, b, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define rson m + 1, r, rt << 1 | 1
#define inf 0x3f3f3f3f
typedef long long ll;
const int N = 100000 + 10;
map<int, int> vis;
int a[N], b[N], c[N];
int main()
{
//freopen("in.txt", "r", stdin);
int n, m;
while (~scanf("%d%d", &n, &m))
{
vis.clear();
for (int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
vis[a[i]] = i;
}
int nn = 0, x;
for (int i = 0; i < m; i++)
{
scanf("%d", &x);
if (vis.find(x) != vis.end())
b[nn++] = vis[x];
}
int len = 0;
for (int i = 0; i < nn; i++)
{
int p = lower_bound(c, c + len, b[i]) - c;
c[p] = b[i];
if (p == len)
len++;
}
printf("%d\n", len);
}
return 0;
}