最长递增子序列nlogn的做法
Posted dwvictor
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最长递增子序列nlogn的做法相关的知识,希望对你有一定的参考价值。
费了好大劲写完的 用线段树维护的 nlogn的做法
再看了一下 大神们写的 nlogn 额差的好远
我写的又多又慢 大神们写的又少又快
时间 空间 代码量 哪个都赶不上大佬们的代码
//这是我写的 #include<iostream> #include<stdio.h> #include<map> #include<vector> #include<algorithm> #include<cstring> using namespace std; const int maxn = 50010; int a[maxn]; int val[maxn<<2]; vector<int>v; int getid(int x){ return lower_bound(v.begin(),v.end(),x)-v.begin()+1; } int query(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R)return val[rt]; int m=(l+r)>>1;int t=0; if(L<=m)t=max(t,query(L,R,l,m,rt<<1)); if(R>m)t=max(t,query(L,R,m+1,r,rt<<1|1)); return t; } void update(int x,int l,int r,int rt,int vv){ if(l==r){ val[rt]=vv; }else{ int m=(l+r)>>1; if(x<=m)update(x,l,m,rt<<1,vv); else update(x,m+1,r,rt<<1|1,vv); val[rt]=max(val[rt<<1],val[rt<<1|1]); } } int main() { int n,ans=0; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",a+i); v.push_back(a[i]); } sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); for(int i=1;i<=n;i++){ int t=getid(a[i]); int vv=query(1,t,1,v.size(),1)+1; ans=max(ans,vv); update(t,1,v.size(),1,vv); } printf("%d ",ans); return 0; }
//这是大神们的 #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<cmath> using namespace std; typedef __int64 ll; #define maxn 50050 ll a[maxn],dp[maxn]; int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%I64d",&a[i]),dp[i]=1; int len=0; for(int i=1;i<=n;i++){ if(i==1){ dp[++len]=a[i]; } else{ if(a[i]>dp[len]){ dp[++len]=a[i]; } else{ int pos=lower_bound(dp+1,dp+len+1,a[i])-dp; dp[pos]=a[i]; } } } printf("%d ",len); }
以上是关于最长递增子序列nlogn的做法的主要内容,如果未能解决你的问题,请参考以下文章