Cod sursa(job #1136023)

Utilizator Cosmin1490Balan Radu Cosmin Cosmin1490 Data 8 martie 2014 18:12:09
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.87 kb
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <iterator>
#include <random>
#include <assert.h>
using namespace std;

const string file = "scmax";

const string infile = file + ".in";
const string outfile = file + ".out";

const int INF = 0x3f3f3f3f; 

//#define ONLINE_JUDGE

vector<int> DP;

class AibMax
{
    public:
        AibMax(int size);
        void update(int x, int val);
        int query(int x);

        inline static int zeros(int x);

    protected:
    private:
        vector<int> _data;
        int _N;
};


AibMax::AibMax(int size)
{
    this->_N = size;
    this->_data.resize(_N + 1, 0);
}

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

void AibMax::update(int x, int val)
{

    for(int i = x; i <= _N; i += zeros(i))
    {
        if(DP[_data[i]] < DP[val])
        {
            _data[i] = val;
        }
    }

}

int AibMax::query(int x)
{
    int result = 0;

    for(int i = x; i > 0; i -= zeros(i))
    {
        if(DP[result] < DP[_data[i]])
        {
            result = _data[i];
        }
    }

    return result;
}
int main()
{
#ifdef ONLINE_JUDGE
	ostream &fout = cout;
	istream &fin = cin;
#else
	fstream fin(infile.c_str(), ios::in);
	fstream fout(outfile.c_str(), ios::out);
#endif	

    int N;
    fin >> N;
    vector<int> A(N + 1);
    for(int i = 1; i <= N; i++)
    {
        fin >> A[i];
    }
    
    vector<int> B = A;
    sort(B.begin(), B.end());
    B.erase(unique(B.begin(), B.end()), B.end());

    vector<int> C(N + 1);
    for(int i = 1; i <= N; i++)
    {
        C[i] = lower_bound(B.begin(), B.end(), A[i]) - B.begin();
    }

    AibMax aib(N);
    DP.resize( N + 1, 0);
    vector<int> prec(N + 1);
    int maxDP = 0;
    int maxI = 0;
    for(int i = 1; i <= N; i++)
    {
        int c = aib.query(C[i] - 1);
        DP[i] = DP[c] + 1;
        prec[i] = c;
        aib.update(C[i], i);
        if(DP[i] > maxDP)
        {
            maxDP = DP[i];
            maxI = i;
        }
    }

    vector<int> Sol;
    while(maxI != 0)
    {
        Sol.push_back(A[maxI]);
        maxI = prec[maxI];
    }
    fout << maxDP << "\n";
    for(vector<int>::reverse_iterator itr = Sol.rbegin();
            itr != Sol.rend();
            itr++)
    {
        fout << *itr << " ";
    }
    fout << "\n";

#ifdef ONLINE_JUDGE
#else
    fout.close();
	fin.close();
#endif
}