Cod sursa(job #2660159)

Utilizator andrei_C1Andrei Chertes andrei_C1 Data 18 octombrie 2020 13:46:01
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("scmax.in");
ofstream fout("scmax.out");
const int NMax=1e5;
int N, v[NMax+5], w[NMax+5], mx;
vector<int>ans;
map<int, int>p;
int up[NMax];
int dp[NMax+5];
class AIB{
private :
    vector<int>_aib;
    int _N;
    inline int zeros(int x){
        return x&(-x);
    }
    inline int Get(int x){
        int ret=0;
        for(int i=x; i>0; i-=zeros(i)){
            ret=max(ret, _aib[i]);
        }
        return ret;
    }
public :
    AIB(int lim){
        _aib=vector<int>(lim+5);
        _N=lim;
    }
    void Update(int x, int value){
        for(int i=x; i<=_N; i+=zeros(i)){
            _aib[i]=max(_aib[i], value);
        }
    }
    int Query(int x){
        return Get(x);
    }
};
int main(){
    fin>>N;
    AIB aib(N);
    for(int i=1; i<=N; i++){
        fin>>v[i];
        w[i]=v[i];
    }
    sort(w+1, w+N+1);
    int k=0;
    for(int i=1; i<=N; i++){
        if(!p[w[i]]){
            p[w[i]]=++k;
        }
    }
    for(int i=1; i<=N; i++){
        int pos=p[v[i]];
        dp[i]=1+aib.Query(pos-1);
        aib.Update(pos, dp[i]);
    }
    int bestp=0;
    for(int i=1; i<=N; i++){
//        cout<<dp[i]<<" ";
        if(dp[i]>dp[bestp]){
            bestp=i;
        }
    }
    fout<<dp[bestp]<<'\n';
    ans.push_back(v[bestp]);
    for(int i=bestp; i>0; i--){
        if(dp[i]==dp[bestp]-1){
            ans.push_back(v[i]);
            bestp=i;
        }
    }
    for(vector<int>::reverse_iterator it=ans.rbegin(); it!=ans.rend(); it++){
        fout<<*it<<" ";
    }
    return 0;
}