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;
}