P1439 【模板】最长公共子序列做题笔记

以前做过两次这题,但都没学会,只是照着题解打了一边,于是重做,第一眼以为 \(O(n^2)\) 的的做法能过,看了眼数据范围发现 \(n \le 10^5\),被卡了,然后看了题解,发现是 \(n \log n\) 的做法,具体就是输入时预处理 \(a_i\) 的位置,数组存储最长公共子序列,然后输入 b,果 b 在 a 中的位置比队列中最后一个数要大,就把 b 在 a 中的位置插入队尾,否则进行二分查找,找到队列中第一个比 b 在 a 中的位置大的数,取小,最后输出存储的长度即可

#include <bits/stdc++.h>
  using namespace std;
int n,l,a[100005],b,t[100005],s[100005],v,i;
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin>>n;
	for (i=1;i<=n;i++)
	{
		cin>>a[i];
		t[a[i]]=i;
		s[i]=0x7fffffff;
	}
	for (i=1;i<=n;i++)
	{
		cin>>b;
		if (t[b]>s[l]) s[++l]=t[b];
		else
		{
			v=upper_bound(s+1,s+l+1,t[b])-s;
			s[v]=min(s[v],t[b]);
		}
	}
	cout<<l<<endl;
	return 0;
}
posted @ 2022-05-11 09:45  Jason142  阅读(24)  评论(0编辑  收藏  举报