题目链接:http://acm.hust.edu.cn/vjudge/problem/19051
题意:两个序列长度为p+1和q+1,且第一个数都为1,每个序列中的数各不相同,范围都在1~n^2内。求A和B的LCS。
思路:由于序列中的数都是唯一的,所以把第一个序列按照1~p+1编号,然后把B序列对于编号后直接求LIS即可。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <utility>
using namespace std;
#define rep(i,j,k) for (int i=j;i<=k;i++)
#define Rrep(i,j,k) for (int i=j;i>=k;i--)
#define Clean(x,y) memset(x,y,sizeof(x))
#define LL long long
#define ULL unsigned long long
#define inf 0x7fffffff
#define mod 100000007
const int maxn = 70000;
int T;
int n,p,q;
map<int,int> pos;
int f[maxn];
int query(int x)
{
int ans = 0;
while( x > 0 )
{
ans = max( ans , f[x] );
x -= x & (-x);
}
return ans;
}
void add(int x,int k)
{
while( x <= n )
{
f[x] = max( k , f[x] );
x += x & (-x);
}
}
void init()
{
int temp;
cin>>n>>p>>q;
n*=n;
pos.clear();
rep(i,1,p+1)
{
scanf("%d",&temp);
pos[temp] = i;
}
Clean(f,0);
}
int solve()
{
int temp;
int ans = 0;
rep(i,1,q+1)
{
scanf("%d",&temp);
if ( pos[temp] == 0 )continue;
temp = pos[temp];
int x = query(temp-1);
add(temp,x+1);
ans = max( ans , x+1 );
}
return ans;
}
int main()
{
cin>>T;
rep(kase,1,T)
{
init();
printf("Case %d: %d\n",kase,solve());
}
return 0;
}