Cod sursa(job #2192377)

Utilizator NOSCOPEPROKENDYMACHEAMACUMVREAU NOSCOPEPROKENDY Data 5 aprilie 2018 20:35:40
Problema Secv Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.05 kb
#include <fstream>
#include <algorithm>

using namespace std;

ifstream fin ("secv.in");
ofstream fout ( "secv.out");

const int Dim = 50001;
int A[Dim],n,poz,Tata[Dim],D[Dim],ma,maxim,lung = 0x3f3f3f3f,index;
pair < int,int > Aux[Dim];
pair <int,int > Tree[Dim * 4];
void Normalization();
void Dynamic();
void Query(int node , int le , int ri , int a , int b);
void Update(int node,  int le , int ri , int pos, int val,int ind);
void Check(int i);


int main() {

    fin >> n;
    for ( int i = 1; i <= n; ++i) {
        fin >> A[i];
        Aux[i] = {A[i] , i};
        }
    Normalization();
    Dynamic();
    bool afis = false;
    for ( int i = 1; i <= n; ++i)
        if (D[i] == maxim) {
            index = i;
            Check(i);
            afis = true;
            }
     if ( afis == true)
        fout << lung;
    else fout << -1;
}

void Normalization() {

    sort(Aux + 1 , Aux + 1 + n);
    Aux[0].first = -0x3f3f3f3f;
    int cnt = 0;
    for ( int i = 1; i <= n; ++i)
        if (Aux[i].first != Aux[i-1].first)
        A[Aux[i].second] = ++cnt , maxim = max(maxim,cnt);

        else  A[Aux[i].second] = cnt;
}

void Dynamic() {

    for ( int i = 1; i <= n; ++i) {
        if ( A[i] == 1) {
            Tata[i] = 0;
            D[i] = 1;
            Update(1,1,n,A[i],D[i],i);
            continue;
            }
            ma = 0; poz = -0x3f3f3f3f;
            Query(1,1,n,1,A[i]-1);
            D[i] = ma + 1;
            Tata[i] = poz;
            Update(1,1,n,A[i],D[i],i);
        }
}

#define fr first
#define p second
void Update(int node, int le,int ri,int pos ,int val,int ind) {

    if(le == ri) {
        if ( Tree[node].fr < val)
        Tree[node] = {val,ind};
        else if (Tree[node].fr == val) Tree[node].p = max(Tree[node].p,ind);
        return ;
    }
    int mj = (le + ri) / 2;
    if( pos <= mj)
        Update(node * 2, le, mj , pos , val,ind);
    else Update(node * 2 + 1 , mj + 1 , ri , pos , val,ind);
        if(Tree[node * 2].fr < Tree[node * 2 + 1].fr)
            Tree[node] = Tree[node * 2 + 1];
        else
           if (Tree[node * 2].fr > Tree[node * 2 + 1].fr)
            Tree[node] = Tree[node * 2];
        else
            if(Tree[node * 2].fr == Tree[node * 2 + 1].fr and Tree[node * 2].p < Tree[node * 2 + 1].p)
                  Tree[node] = Tree[node * 2 + 1];
        else Tree[node] = Tree[node * 2];
}
void Query(int node , int le , int ri , int a , int b){
        if(a <= le and b >= ri) {
        if(ma < Tree[node].fr) {
            ma = Tree[node].fr;
            poz = Tree[node].second;
            }
        else
        if ( ma == Tree[node].fr) {
            poz = max(poz,Tree[node].p);
            }
        return ;
        }
    int mj = (le + ri) / 2;
    if(a <= mj)
        Query(2 * node, le , mj, a , b);
    if(b > mj)
        Query(2 * node + 1, mj + 1 , ri ,a , b);
}

void Check(int i) {

    if (Tata[i] == 0) {
        lung = min(index - i + 1 , lung);
        return;
    }
    Check(Tata[i]);

}