思路:因為n<=1e5,所以不能O(n方)的復雜度,所以常規的計算最長公共子序列的方法就不行,不過這題有個特點,就是a,b都是排列,那么a有的數b也有,并且數量還一樣,那么我們只要把b數在a中的位置記錄下來,也就是m[b[i]],然后因為子序列是順序的,所以對應的位置就必須是遞增的,也就是我們假設有一個新的數組比如c,c[i]就是m[b[i]]就是b的數在a的哪個位置(其實就是下標),然后我們對c數組求最大遞增子序列,就是O(nlogn)的復雜度,這個做法的含義就是,我們在a中找一個順序的子序列,因為下標遞增就是順序嘛,然后因為我們是用我們的b也是順序的,那么就也有這個子序列,然后就是最長公共子序列。
代碼:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,i,j;
vector<ll>a(100005),b(100005),en,m(100005);//en是求最長遞增子序列的end數組,m相當于記錄b的數在a的位置
int main(){ios::sync_with_stdio(false);cin.tie(0);cin>>n;for(i=1;i<=n;i++){cin>>a[i];m[a[i]]=i;//記錄位置}for(i=1;i<=n;i++){cin>>b[i];}for(i=1;i<=n;i++){auto x=upper_bound(en.begin(),en.end(),m[b[i]]);//對m[b[i]]操作,其實就是我們剛剛說的c數組,剩下的就是求最長遞增子序列的模板if(x==en.end()){en.push_back(m[b[i]]);}else{en[x-en.begin()]=m[b[i]];}}cout<<en.size();return 0;
}