表面上看这是一道LCS问题
LCS问题O(n2)的复杂度已经很优秀了
而这道题需要O(nlogn)以下的复杂度才能AC
所以我们要找经典问题的特殊性
特殊就在这两个串中,每个数字都是恰好出现5次
不难想到先预处理每个数在B串依次出现的位置
先扫一遍A串,对于每一个数a[i],设f[j]=LCS(i,j)
显然这个数在B串出现的位置才会更新答案
对于每个出现的位置x1~x5,显然f[x]=max(f[w])+1 (1<=w<=x-1);
为了避免重复更新,我们要从后往前更新f[x]
再考虑怎么快速找到最大值,显然这里要找的是前缀中的最大值
不难想到,我们可以通过树状数组维护
1 var b,f,a,c:array[0..100010] of longint; 2 w:array[0..100010,0..5] of longint; 3 j,n,i,x,ans:longint; 4 5 function max(a,b:longint):longint; 6 begin 7 if a>b then exit(a) else exit(b); 8 end; 9 10 function lowbit(x:longint):longint; 11 begin 12 exit(x and (-x)); 13 end; 14 15 function get(x:longint):longint; 16 begin 17 get:=0; 18 while x>0 do 19 begin 20 get:=max(get,c[x]); 21 x:=x-lowbit(x); 22 end; 23 end; 24 25 procedure update(x,p:longint); 26 begin 27 while x<=5*n do 28 begin 29 c[x]:=max(c[x],p); 30 x:=x+lowbit(x); 31 end; 32 end; 33 34 begin 35 readln(n); 36 for i:=1 to 5*n do 37 read(a[i]); 38 for i:=1 to 5*n do 39 begin 40 read(x); 41 inc(b[x]); 42 w[x,b[x]]:=i; 43 end; 44 for i:=1 to 5*n do 45 begin 46 for j:=5 downto 1 do 47 begin 48 x:=w[a[i],j]; 49 f[x]:=get(x-1)+1; 50 update(x,f[x]); 51 end; 52 end; 53 for i:=1 to 5*n do 54 ans:=max(f[i],ans); 55 writeln(ans); 56 end.