题意很简单,就是求两组数据的最长公共子序列的长度,常规方法求时间复杂度O(pq)肯定超时,因为p,q的范围上限是62500,这个题隐含了一个条件是这两个数组中各个元素互不相同,这样就可以把A数组中的元素重新编号为1,2,3....p+1,然后B数组根据A数组的数据也换成一一对应的编号,这样问题就转换成求B数组的最长递增子序列。时间复杂度可以降低为nlogn
#include<stdio.h> #include<string.h> int Kase=0; int A[70000],B[70000],d[70000]; int query(int l,int r,int k) { int m=(l+r)/2; while(l<r) { if(d[m]>k) r=m; else { if(l==m) break; l=m; } m=(l+r)/2; } if(k<=d[l]) return l; return r; } int main() { int T; scanf("%d",&T); while(T--) { int i,t,n,p,q; scanf("%d%d%d",&n,&p,&q); memset(A,0,sizeof(A)); for(i=1;i<=p+1;i++) { scanf("%d",&t); A[t]=i; } for(i=1;i<=q+1;i++) { scanf("%d",&t); B[i]=A[t]; } int ans=0; memset(d,0,sizeof(d)); for(i=1;i<=q+1;i++) { if(B[i]>d[ans]) d[++ans]=B[i]; else if(B[i]) { int k=query(1,ans,B[i]); d[k]=B[i]; } } printf("Case %d: %d\n",++Kase,ans); } }