最長上升子序列LIS,O(nlogn)做法
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 #define MAX 1000000 5 6 int n; 7 int a[MAX]; 8 int d[MAX]; 9 int cnt; 10 int pos[MAX]; 11 int inv; 12 13 int find(int l,int r,int x){ 14 if(l==r) 15 return r; 16 int mid=(l+r)>>1; 17 if(d[mid]>x) 18 return find(l,mid,x); 19 return find(mid+1,r,x); 20 } 21 22 stack<int>sav; 23 24 int main(){ 25 scanf("%d",&n); 26 for(int i=1;i<=n;i++){ 27 scanf("%d",&a[i]); 28 if(a[i]>d[cnt]){ 29 d[++cnt]=a[i]; 30 pos[i]=cnt; 31 } 32 else{ 33 pos[i]=find(1,cnt,a[i]); 34 d[pos[i]]=a[i]; 35 } 36 } 37 for(int i=n;i>0;i--) 38 if(pos[i]==cnt){ 39 sav.push(a[i]); 40 cnt--; 41 } 42 while(!sav.empty()){ 43 printf("%d ",sav.top()); 44 sav.pop(); 45 } 46 }