https://www.luogu.org/problem/show?pid=1439
这个一看就是n*n的暴力嘛,但是n有点大…
因为是两个排列,换句话说没有重复的数字;
那我们可以转化一下
比如样例
5
3 2 1 4 5
1 2 3 4 5
我们把下面一行的值变成上面一行的位置
3 2 1 4 5
那么直接最长上升子序列就好了
为什么呢?
比如第二行第一个数1
如果我们选了1,那么后面是不是只可以选择在第一行1后面的数了;
就是这个道理;
然后对于最长上升子序列我们有一个基于单调栈和二分的算法n*logn
就是维护一个递增的栈;
当前我们的值是x;
如果x>栈顶,那么直接加入;
不然我们就二分找到第一个大于x的数,直接替换;
因为x之后的数,全可以接在x的后面,所以直接替换就可以了;
最后答案就是栈的高度;
但是方案并不是栈的元素;
不好意思,这种方法不可以记录方案的;
#include<bits/stdc++.h>
#define Ll long long
using namespace std;
const int N=1e5+5;
int f[N],a[N],v[N],top;
int n,m,x,ans;
int er(int x){
if(x>v[top])return ++top;
int l=1,r=top,ans,mid;
while(r>=l){
mid=l+r>>1;
if(v[mid]>x)ans=mid,r=mid-1;else l=mid+1;
}
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&x),f[x]=i;
for(int i=1;i<=n;i++){
scanf("%d",&x);
v[er(f[x])]=f[x];
}
printf("%d",top);
}