最长公共子序列,洛谷之提高历练地,提高模板-nlogn数据结构
正题
让你用Dp做,FFT了吧。(Fast,Fast,TLE).
n的平方明显是不行的。我们来尝试一下新的方法,我们把第一个序列从1到n来编号
int x; scanf("%d",&x); where[x]=i;
我们把他们的值所对应的编号记录下来。
接着,我们把另外一个序列的值改成所对应的编号
s[i]=where[x];
我们现在就可以直接搞一便最长上升子序列即为答案,为什么???因为第一个序列式按编号递增的,而第二个的序列直接对应到第一个序列的每个值,相当于就是按顺序选择。
二分啊!logn 单调上升队列op
#include<cstdio> #include<cstdlib> #include<cstring> int n; int len=0; int where[100010]; int s[100010]; int op[100010]; int max=0; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ int x; scanf("%d",&x); where[x]=i; } for(int i=1;i<=n;i++){ int x; scanf("%d",&x); s[i]=where[x]; } len=max=1; op[1]=s[1]; for(int i=2;i<=n;i++){ int x=s[i]; int l=1,r=len; int ans=0; if(x>op[len]) op[++len]=x; else while(l<=r){ int mid=(l+r)/2; if(x<op[mid]) { r=mid-1; ans=mid; } else l=mid+1; } if(op[ans]>x) op[ans]=x; } printf("%d",len); }