1254 - lcs (n*logn)

1254 - lcs

  • Time Limit: 3000 ms
  • Memory Limit: 65535 Kb

Description

This problem seems a little easy. Because the two given sequences p1 p2 are just  permutations of 1~n. So try it and tell me the answer what the length of longest common subsequence is.

Input

There are some cases following. In each case , containing a positive integer n. 1<=n<=100000. Following are two permutations of 1~n.

Output

Output the length of longest common subsequence

Sample Input

5
1 5 3 2 4
5 3 4 2 1

Sample Output

3

Author

Administrator

Source

The First ACM-ICPC Nanjing Invitational Tournament

 

最长公共子序列向最长递增子序列退化:

  设有序列A,B。记序列A中各个元素在B 中的位子(降序排列),然后按在A中的位置依次列出按后求A的最长递增子序列。

  例如:有A={a,b,a,c,x},B={b,a,a,b,c,a}则有a={6,3,2},b={4,1},c={5};x=/;(注意降序排列)

然后按A中次序排出{a(6,3,2),b(4,1),a(6,3,2),c(5),x()}={6,3,2,4,1,6,3,2,5};对此序列求最长递增子序列即可

 

#include <vector>
#include <cstring>
#include <memory>
#include <algorithm>
#include <cstdio>
using namespace std;

#define MAX 100001
int A[MAX], B[MAX], D[MAX];
int pos[MAX], hash[MAX];

int bfind ( int l, int r, int key )
{
	int mid;
	while ( l < r )
	{
		mid = ( l + r ) / 2;
		if ( key <= D[mid] )
			r = mid;
		else
			l = mid + 1;
	}
	return r;
}


int main()
{
	int n;
	while ( scanf("%d",&n) != -1 )
	{
		int len = 0, i;

		for ( i = 1; i <= n; i++ )
		{
			scanf("%d",&A[i]);
			hash[A[i]] = i;
		}

		for ( i = 1; i <= n; i++ )
		{
			scanf("%d",&B[i]);
			pos[i] = hash[B[i]];
		}


		D[0] = 0;
		for ( i = 1; i <= n; i++ )
		{
			if ( pos[i] > D[len] )
				D[++len] = pos[i];
			else
			{
				int p = bfind ( 1, len, pos[i] );
				D[p] = pos[i];
			}
			
		}
		printf("%d\n",len);
	}
	return 0;
}

			


 

你可能感兴趣的:(1254 - lcs (n*logn))