Cod sursa(job #706092)

Utilizator Teodor94Teodor Plop Teodor94 Data 5 martie 2012 16:32:38
Problema Subsir crescator maximal Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.11 kb
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;

const int N = 100005;

struct normalizare {
    int val, norm;
};

struct Event {
    int start, finish;
    int val;
    int type; // e query sau update

    inline bool operator<(const Event& other) const {
        int index_this = type == 0 ? start : finish;
        int index_other = other.type == 0 ? other.start : other.finish;

        if (index_this != index_other)
            return index_this < index_other;
        if (type != other.type) return type == 0;
        return false;
    }
};

Event event_a, event_b;

void f() {
    if (event_a < event_b) {
    }
}

int n, a[N], lg[N], lgmax = -1;
normalizare cop[N];

bool comp(normalizare x, normalizare y) {
    return x.val < y.val;
}

void citire() {
    scanf("%d", &n);

    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
}

int cautbin(int x) {
    int i, pas = 1 << 17;

    for (i = 0; pas; pas >>= 1)
        if (i + pas <= n && cop[i + pas].val <= x)
            i += pas;

    return cop[i + pas].norm;
}

void normalizare() {
    for (int i = 1; i <= n; ++i)
        cop[i].val = a[i];

    sort(cop + 1, cop + n + 1, comp);

    int curent = 1;
    for (int i = 1; i <= n; ++i) {
        cop[i].norm = curent;

        if (i < n && cop[i].val < cop[i + 1].val)
            ++curent;
    }

    for (int i = 1; i <= n; ++i) {
        a[i] = cautbin(a[i]);
    }
}

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

int query(int x) {
    int curent = x, max = 0;

    while (curent) {
        if (lg[curent] > max)
            max = lg[curent];

        curent -= val(curent);
    }

    return max;
}

void update(int poz, int v) {
    int curent = poz;

    while (curent <= n) {
        lg[curent] = max(lg[curent], v);

        curent += val(curent);
    }
}

void rez() {
    for (int i = 1; i <= n; ++i) {
        int x = query(a[i] - 1) + 1;

        lgmax = max(lgmax, x);

        update(a[i], x);
    }
    printf("%d\n", lgmax);
}

int main() {
    freopen("scmax.in", "r", stdin);
    freopen("scmax.out", "w", stdout);

    citire();

    normalizare();

    rez();

    return 0;
}