Cod sursa(job #1470521)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 11 august 2015 16:35:09
Problema Secv Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.02 kb
#include <fstream>
#include <algorithm>
#include <vector>

using namespace std;

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

const int MAX_N = 5000;
const int INF = 0x7fffffff;

int n_Norm, n;
int N[MAX_N + 1];
int A[MAX_N + 1];
int V[MAX_N + 1];
int V_Norm[MAX_N + 1];
int Last[MAX_N + 1];
int nextSame[MAX_N + 1];
int nextBigger[MAX_N + 1];
vector < int > waitingList[MAX_N + 1];

int getNorm(int x) {
    int left = 1, right = n_Norm, mid;
    while(left <= right) {
        mid = (left + right) / 2;
        if(N[mid] < x) left = mid + 1;
        else if(N[mid] > x) right = mid - 1;
        else return mid;
    }
}

void processLast() {
    int i, x;
    for(i = 1; i <= n; i++) {
        x = V_Norm[i];
        nextSame[Last[x]] = i;
        Last[x] = i;
    }
    for(i = 1; i <= n; i++) {
        x = V_Norm[i];
        while(!waitingList[x-1].empty()) {
            nextBigger[waitingList[x-1].back()] = i;
            waitingList[x-1].pop_back();
        }
        waitingList[x].push_back(i);
    }
    for(i = 1; i <= n; i++) {
        if(nextSame[i] == 0) nextSame[i] = n + 1;
        if(nextBigger[i] == 0) nextBigger[i] = n + 1;
    }
}

int get_substrLen(int pos) {
    int initPos = pos;
    for(; V_Norm[pos] < n_Norm && pos <= n; pos = nextBigger[pos]);
    if(pos > n) return INF;
    else return pos - initPos + 1;
}

int main() {
    int i, j, ret = INF, len;

    in >> n;
    for(i = 1; i <= n; i++) {
        in >> A[i];
        V[i] = A[i];
    }

    sort(A+1, A+n+1);
    for(i = 1, n_Norm = 1; i <= n; i++) {
        while(A[i] == A[i+1]) i++;
        N[n_Norm++] = A[i];
    }
    n_Norm--;
    for(i = 1; i <= n; i++) {
        V_Norm[i] = getNorm(V[i]);
    }

    processLast();
    for(i = 1; i <= n - n_Norm + 1; i++) {
        if(V_Norm[i] == 1 && nextSame[i] > nextBigger[i]) {
            len = get_substrLen(i);
            ret = min(ret, len);
        }
    }

    if(ret == INF) ret = -1;
    out << ret << "\n";

    return 0;
}