[UVA 10635] Prince ans Princess

时间:2023-03-08 16:59:48

图片加载可能有点慢,请跳过题面先看题解,谢谢
[UVA 10635] Prince ans Princess

[UVA 10635] Prince ans Princess

[UVA 10635] Prince ans Princess

[UVA 10635] Prince ans Princess

这道题。。。
还是要点思维的。。。
第一眼看是个最长公共子序列,但是, \(N\le 62500\) ,并不能 \(O(n^2)\) 求
$
$
这道题有个很好的性质,每个序列中的元素互不相同
也就是说,在一个序列中,每一个数字都有一个唯一的位置
这有什么用?
$
$
我们进行这样一个操作,把 \(b\) 序列中的数字换成该数字在 \(a\) 序列中出现的位置,那么问题就变成了一个求 \(b\) 序列的 \(LCS\) 的问题了
这样我们就可以在 \(O(nlogn)\) 的复杂度下解决这个问题

再吐槽一下。。。
做这道题目,思考 \(10min\) ,代码调试 \(2h\) ,震惊,原因竟是?
看下这个语句:
我写的: \(a[++k]=max(a[k],x)\)
AC程序: \(a[k+1]=max(a[k+1],x)\),或者 \(a[k]=max(a[++k],x)\)

//made by Hero_of_Someone
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define il inline
#define RG register
using namespace std;
il int gi(){ RG int x=0,q=1; RG char ch=getchar(); while( ( ch<'0' || ch>'9' ) && ch!='-' ) ch=getchar();
  if( ch=='-' ) q=-1,ch=getchar(); while(ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x; }

int T,t,N,n,m,cnt;
int a[100010],b[100010],id[100010];

il void init(){
   N=gi(),n=gi()+1,m=gi()+1;
   memset(id,0,sizeof(id)); cnt=0;
   for(RG int i=1;i<=n;i++) a[i]=gi(),id[a[i]]=i;
   for(RG int i=1;i<=m;i++){ b[i]=gi();
      if(id[b[i]]) b[++cnt]=id[b[i]];
   }
}

il void work(){
   n=cnt,cnt=0;
   memset(a,0x3f3f3f3f,sizeof(a));
   for(RG int i=1;i<=n;i++){
      RG int x=b[i];
      RG int l=1,r=cnt,k=0;
      while(l<=r){
         RG int mid=(l+r)>>1;
         if(a[mid]>x) r=mid-1;
         else l=mid+1,k=mid;
      }
      if(k==cnt) a[++cnt]=x;
      else a[k]=min(a[++k],x);
   }
   printf("Case %d: %d\n",t,cnt);
}

int main(){ T=gi(); for(t=1;t<=T;t++){ init(); work(); } return 0; }