Cod sursa(job #1202197)

Utilizator IonMosnoiIon Mosnoi IonMosnoi Data 27 iunie 2014 11:41:43
Problema Subsir crescator maximal Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2.27 kb
#include<fstream>
#include<algorithm>
using namespace std;
using namespace std;
ifstream f("scmax.in");
ofstream o("scmax.out");

int a[100100],b[201000],c[102000],d[102000],n,best[100100],last,sol=0;
void sortq(int l,int r){
    int m=d[(l+r)/2],i=l,j=r;
    do{
        while(m>d[i])i++;
        while(m<d[j])j--;
        if(i<=j){
            swap(c[i],c[j]);
            swap(d[i],d[j]);
            j--;
            i++;
        }
    }while(i<=j);
    if(i<r)sortq(i,r);
    if(j>l)sortq(l,j);
}
void sortq1(int l,int r){
    int m=c[(l+r)/2],i=l,j=r;
    do{
        while(m>c[i])i++;
        while(m<c[j])j--;
        if(i<=j){
            swap(c[i],c[j]);
            swap(d[i],d[j]);
            j--;
            i++;
        }
    }while(i<=j);
    if(i<r)sortq1(i,r);
    if(j>l)sortq1(l,j);
}
int qeury(int p,int q,int l,int r,int nod){
     if(p>q)return 0;
     if(l>=p && q>=r)return b[nod];
     int m = (r+l)/2,sol=0;
     if(m>=p) sol = max(sol,qeury(p,q,l,m,2*nod));
     if(m+1<=q) sol = max(sol,qeury(p,q,m+1,r,2*nod+1));
     return sol;
}

void update(int q,int v,int l,int r,int nod){
if(l==r){b[nod] = v; return;}
int m = (l+r)/2;
if(m>=q) update(q,v,l,m,nod*2);
else update(q,v,m+1,r,nod*2+1);
b[nod] = max(b[nod*2],b[nod*2+1]);
}

int main(){
f>>n;
for(int i=1;i<=n;i++)f>>a[i];
int lm=0;
for(int i=1;i<=n;i++){
   if(i==1 ||(i>1 && a[i]!=a[i-1])){
    d[++lm]=a[i];c[lm]=lm;
    a[lm] = a[i];

   }
}
//o<<lm<<"\n";
for(int i=1;i<=2*lm;i++)b[i]=0;
sortq(1,lm);

int ok=1,id=1;
for(int i=2;i<=lm;i++)
    if(d[i]==d[id]){
        ok++;
    }else{
      if(ok>1)sortq1(id,id+ok-1);
      id = i;
      ok=1;
    }
id = 1;
for(int i=2;i<=lm;i++)
    if(d[i]==d[id]){
        c[i] = c[id];
    }else id = i;
//for(int i=1;i<=lm;i++)o<<c[i]<<" ";o<<endl;
int lung;
for(int i=lm;i;i--){

    lung = qeury(c[i]+1,lm,1,lm,1);
   // o<<c[i]<<" "<<lung<<endl;
    best[i] = lung +1;
    if(best[i]>sol){
        sol=best[i];
        last = i;
    }
    update(c[i],lung+1,1,lm,1);
  //  o<<best[i]<<endl;
}
o<<sol<<"\n";
int val = d[last];
o<<d[last]<<" ";sol--;
for(int i=last+1;i<=lm;i++)
     if(best[i]==sol  && d[i]>val){
        o<<d[i]<<" ";
        sol--;
        val = d[i];
     }
}