Cod sursa(job #2265821)

Utilizator NToniBoSSNicolae Tonitza NToniBoSS Data 21 octombrie 2018 18:53:59
Problema Subsir 2 Scor 45
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.05 kb
#include <bits/stdc++.h>
#define LIM 1<<17
/// TONI BO$$ was here
/// #MLC

using namespace std;
char BUF[LIM];
int poz;

inline char getChar(){
    poz++;
    if(poz>=LIM){
    	fread(BUF,LIM,1,stdin);
    	poz=0;
    }
    return BUF[poz];
}

inline int getNr(){
    int r=0, semn=1;
    char ch=getChar();
    while(isdigit(ch)==0 && ch!='-') ch=getChar();
    if(ch=='-'){
        semn=-1;
        ch=getChar();
    }
    while(isdigit(ch)!=0){
        r=r*10+semn*(ch-'0');
        ch=getChar();
    }
    return r;
}

pair <int,int> v[5001],aib[5001],rez[5001];
int urmmax[5002],n;
vector <int> sol;

bool comp(pair <int,int> a,pair<int,int> b)
{
    if(a.first==b.first)
        return a.second<b.second;
    return a.first<b.first;
}

int zeros(int x)
{
    return (x^(x-1))&x;
}

pair <int,int> query(int i)
{
    pair <int,int> rez={0,0};
    for(int ct=i; ct>0; ct-=zeros(ct))
        if(rez.first<aib[ct].first)
            rez=aib[ct];
    return rez;
}

void update(int i,int x,int ult)
{
    for(int ct=i; ct<=n; ct+=zeros(ct))
        if(aib[ct].first<x)
            aib[ct]={x,ult};
}

int main()
{
    int i,p,lgmin;
    freopen("subsir2.in","r",stdin);
    freopen("subsir2.out","w",stdout);
    n=getNr();
    for(i=1; i<=n; i++)
    {
        v[i].first=getNr()+1000001;
        v[i].second=i;
    }
    for(i=n; i>0; i--)
        urmmax[i]=max(urmmax[i+1],v[i].first);
    sort(v+1,v+1+n,comp);
    lgmin=5001;
    p=0;
    for(i=1; i<=n; i++)
    {
        pair <int,int> z=query(v[i].second);
        rez[i]={z.first+1,z.second};
        update(v[i].second,rez[i].first,i);
        if(urmmax[v[i].second+1]<v[i].first)
            if(rez[i].first<lgmin)
            {
                lgmin=rez[i].first;
                p=i;
            }
    }
    printf("%d\n",lgmin);
    while(p)
    {
        sol.push_back(v[p].second);
        p=rez[p].second;
    }
    while(!sol.empty())
    {
        printf("%d ",sol.back());
        sol.pop_back();
    }

    return 0;
}