Cod sursa(job #1464731)

Utilizator fanache99Constantin-Buliga Stefan fanache99 Data 24 iulie 2015 13:33:14
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.08 kb
#include<cstdio>
#include<algorithm>
using namespace std;
int n,vn[100005],v[100005],lst[100005],lmax[100005],aib[100005],up[100005],aux[100005];
void update(int x,int poz){
    for(x;x<=n;x+=(x^(x-1)&x))
        if(lmax[poz]>lmax[aib[x]])
            aib[x]=poz;
}
int query(int x){
    int poz=0;
    for(x;x>0;x-=(x^(x-1)&x))
        if(lmax[aib[x]]>lmax[poz])
            poz=aib[x];
    return poz;
}
void interclasare(int left,int right){
    int i=left,j=(left+right)/2+1,k=left-1;
    while(i<=(left+right)/2&&j<=right)
        if(lst[i]>lst[j]){
            k++;
            aux[k]=lst[j];
            j++;
        }
        else{
            k++;
            aux[k]=lst[i];
            i++;
        }
    while(i<=(left+right)/2){
        k++;
        aux[k]=lst[i];
        i++;
    }
    while(j<=right){
        k++;
        aux[k]=lst[j];
        j++;
    }
    for(i=left;i<=right;i++)
        lst[i]=aux[i];
}
void merge_sort(int left,int right){
    int mij=(left+right)/2,aux;
    if(left==right)
        return;
    if(left==right-1){
        if(lst[left]>lst[right]){
            aux=lst[left];
            lst[left]=lst[right];
            lst[right]=aux;
        }
    }
    merge_sort(left,mij);
    merge_sort(mij+1,right);
    interclasare(left,right);
}
int main(){
    freopen("scmax.in", "r", stdin);
    freopen("scmax.out", "w", stdout);
    int i,h=1,maxim=-1,poz;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        scanf("%d",&v[i]);
        vn[i]=lst[i]=v[i];
    }
    merge_sort(1,n);
    for(i=2;i<=n;i++)
        if(lst[i]!=lst[h])
            lst[++h]=lst[i];
    for(i=1;i<=n;i++)
        vn[i]=lower_bound(lst+1,lst+h+1,v[i])-lst;
    for(i=1;i<=n;i++){
        up[i]=query(vn[i]-1);
        lmax[i]=lmax[up[i]]+1;
        update(vn[i],i);
        if(lmax[i]>maxim){
            maxim=lmax[i];
            poz=i;
        }
    }
    printf("%d\n",maxim);
    for(i=maxim;i>=1;i--){
        lst[i]=v[poz];
        poz=up[poz];
    }
    for(i=1;i<=maxim;i++)
        printf("%d ",lst[i]);
    return 0;
}