Cod sursa(job #1424436)

Utilizator auRSTARHreapca Aurelian auRSTAR Data 24 aprilie 2015 13:02:21
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.65 kb
#include <iostream>
#include <deque>
#include <vector>
#include <cstring>
#include <algorithm>
#define step(x) (x & (-x))
using namespace std;

int N, i, A[100010], B[100010], cnt, last, sol, position, DP[100010], prevs[100010], solution[100010];
vector<pair<int,int> > V;
int AIB[100010], pos[100010];

int query(int x)
{
    int res = 0, p = 0;
    for( ; x; x -= step(x))
        if(AIB[x] > res)
        {
            res = AIB[x];
            p = pos[x];
        }
    prevs[i] = p;
    return res;
}

void update(int val, int p, int x)
{
    for(; x <= N; x+=step(x))
        if(AIB[x] < val)
        {
            AIB[x] = val;
            pos[x] = p;
        }
}

void afiseaza(int x)
{
    if(!DP[x])return;
    afiseaza(prevs[x]);
    printf("%d ", A[x]);
}

int main()
{
    freopen("scmax.in","r",stdin);
    freopen("scmax.out","w",stdout);
    scanf("%d", &N);
    for(i = 1; i <= N; i++)
    {
        scanf("%d", &A[i]);
        V.push_back(make_pair(A[i], i));
    }
    sort(V.begin(), V.end());
    last = -1;
    cnt = 0;
    for(vector<pair<int,int> >::iterator it = V.begin(); it != V.end(); it++)
    {
        if(it->first != last)
        {
            last = it->first;
            cnt = cnt + 1;
        }
        B[it->second] = cnt;
    }
    for(i = 1; i <= N; i++)
    {
        DP[i] = query(B[i] - 1) + 1;
        if(sol < DP[i])
        {
            sol = DP[i];
            position = i;
        }
        update(DP[i], i, B[i]);
    }
    printf("%d\n", sol);
    while(DP[position])
    {
        solution[DP[position]] = A[position];
        position = prevs[position];
    }
    for(i=1;i<=sol;i++)
        printf("%d ",solution[i]);
    return 0;
}