Cod sursa(job #2268489)

Utilizator SqueekDanielTodasca Daniel SqueekDaniel Data 24 octombrie 2018 21:06:46
Problema Subsir crescator maximal Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.47 kb
#include <bits/stdc++.h>

#define Middle (Left+Right)/2
#define MaxN   100005

std::ifstream InFile("scmax.in");
std::ofstream OutFile("scmax.out");

int N, V[MaxN];
int LIS[MaxN],
    Prev[MaxN];

int SegmTree[4*MaxN];

int Query(int A, int B, int Left = 1, int Right = N, int SegmIndex = 1) {
    if (A <= Left && Right <= B)
        return SegmTree[SegmIndex];

    int Max = 0, query;
    if (A <= Middle) {
        query = Query(A, B, Left, Middle, 2*SegmIndex);
        if (LIS[Max] < LIS[query])
            Max = query;
    }
    if (B > Middle) {
        query = Query(A, B, Middle+1, Right, 2*SegmIndex+1);
        if (LIS[Max] < LIS[query])
            Max = query;
    }

    return Max;
}

void Update(int Index, int Val, int Left = 1, int Right = N, int SegmIndex = 1) {
    if (Index < Left || Index > Right)
        return;

    if (Left == Right) {
        SegmTree[SegmIndex] = Val;
        return;
    }

    Update (Index, Val, Left, Middle, 2*SegmIndex);
    Update (Index, Val, Middle+1, Right, 2*SegmIndex+1);

    if (LIS[SegmTree[2*SegmIndex]] > LIS[SegmTree[2*SegmIndex+1]])
        SegmTree[SegmIndex] = SegmTree[2*SegmIndex];
    else
        SegmTree[SegmIndex] = SegmTree[2*SegmIndex+1];
}

struct DataStruct {
    int val, index;
    bool operator < (const DataStruct &Other) const {
        if (val == Other.val)
            return index < Other.index;
        return val < Other.val;
    }
    bool operator == (const DataStruct &Other) const {
        return (val == Other.val);
    }
}   SortData[MaxN];

int Best;
void Print(int Find = Best, int From = N) {
    if (Find == 0) return;
    for (int i=From; i>0; --i)
        if (LIS[i] == Find) {
            Print(Find-1, i);
            OutFile << V[i] << ' ' ;
            return;
        }
}

void Citire() {
    int NRead; InFile >> NRead;
    for (int i=0, x; i<NRead; ++i) {
        InFile >> x;
        if (x != V[i]) {
            V[++N] = x;
            SortData[N] = {V[N], N};
        }
    }
}

void Rezolvare() {
    std::sort (SortData+1, SortData+N+1);

    for (int i=0, index; i<N; ++i) {
        index = SortData[i+1].index;

        Prev[index] = Query(1, index);
        LIS[index] = LIS[Prev[index]] + 1;
        Update(index, index);
    }

    for (int i=0; i<N; ++i)
        Best = std::max(Best, LIS[i+1]);
    OutFile << Best << '\n';
    Print();
}

int main()
{
    Citire();
    Rezolvare();

    return 0;
}