您的位置:首页 > 其它

UVA 10635 Prince and Princess

2017-10-12 11:02 423 查看
题意就是给你两个自身不会有重复元素的数列,求最长公共子序列,O(nlogn)。

去年(?)做过一遍的题现在想想还是很巧妙。

想一想,枚举B的数B[i],看它在A的哪里(丢进桶里维护)。如果有,怎么计算它的答案。

如果有的话,对于一个B[j](j<i),可以转移到它,就是要有:

[b]

#include    <iostream>
#include    <cstdio>
#include    <cstdlib>
#include    <algorithm>
#include    <vector>
#include    <cstring>
#include    <queue>
#include    <complex>
#include    <stack>
#define LL long long int
#define dob double
#define lb(x) (x&-x)
#define FILE "10635"
using namespace std;

const int N = 70010;
int n,p,q,bin
,T
,Ans;

inline int gi(){
int x=0,res=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')res*=-1;ch=getchar();}
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*res;
}

inline int query(int x,int res=0){
for(;x;x-=lb(x))res=max(res,T[x]);
return res;
}

inline void update(int x,int val){
for(;x<=n*n;x+=lb(x))T[x]=max(T[x],val);
}

inline void solve(){
n=gi();p=gi()+1;q=gi()+1;Ans=0;
memset(bin,0,sizeof(bin));memset(T,0,sizeof(T));
for(int i=1;i<=p;++i)bin[gi()]=i;
for(int i=1;i<=q;++i){
int y=bin[gi()];if(!y)continue;
int v=query(y)+1;if(v>Ans)Ans=v;
update(y,v);
}
printf("%d\n",Ans);
}

int main()
{
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
int Case=gi();
for(int t=1;t<=Case;++t)
printf("Case %d: ",t),solve();
fclose(stdin);fclose(stdout);
return 0;
}


Prince and Princess
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: