1. 程式人生 > 其它 >P1439 【模板】最長公共子序列做題筆記

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