思路:因为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;
}