最长递增子序列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);
} 
View Code
原文地址:https://www.cnblogs.com/DWVictor/p/10283198.html