# 题目1533：最长上升子序列 （nlogn | 树状数组）

http://ac.jobdu.com/problem.php?pid=1533

4
4 2 1 3
5
1 1 1 1 1

2
1
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>

using namespace std;

const int N=110000;

int n,val[N];
vector<int> vt;

int binarySearch(int x){
int left=0,right=vt.size()-1;
int mid;
while(left<=right){
mid=(left+right)>>1;
if(vt[mid]<x)
left=mid+1;
else
right=mid-1;
}
return left;
}

int main(){

//freopen("input.txt","r",stdin);

while(~scanf("%d",&n)){
vt.clear();
for(int i=0;i<n;i++)
scanf("%d",&val[i]);
int tmp;
for(int i=0;i<n;i++){
tmp=binarySearch(val[i]);
if(tmp>=(int)vt.size())
vt.push_back(val[i]);
else
vt[tmp]=val[i];
}
int ans=vt.size();
printf("%d\n",ans);
}
return 0;
}

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int N=110000;

int n,val[N],a[N];
int len,arr[N];

int lowbit(int x){
return x&(-x);
}

void update(int i,int x){
while(x<=len){
if(i>arr[x])
arr[x]=i;
x+=lowbit(x);
}
}

int query(int x){
int ans=0;
while(x){
if(arr[x]>ans)
ans=arr[x];
x-=lowbit(x);
}
return ans;
}

int main(){

freopen("input.txt","r",stdin);

while(~scanf("%d",&n)){
for(int i=0;i<n;i++){
scanf("%d",&val[i]);
a[i]=val[i];
}
sort(a,a+n);
len=unique(a,a+n)-a;
memset(arr,0,sizeof(arr));
int ans=1,tmp;
for(int i=0;i<n;i++){
val[i]=lower_bound(a,a+len,val[i])-a+1;
tmp=query(val[i]-1)+1;
if(tmp>ans)
ans=tmp;
update(tmp,val[i]);
}
printf("%d\n",ans);
}
return 0;
}

posted @ 2013-09-21 21:46  Jack Ge  阅读(2572)  评论(0编辑  收藏  举报