Cod sursa(job #1700964)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 11 mai 2016 21:21:25
Problema Secv Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.78 kb
#include <bits/stdc++.h>
using namespace std;

const int NMAX = 5005;
const int  INF = 1e9;
const int   MB = 1<<20;

struct PII {
    int val, poz;
};

PII v[NMAX];
int l[NMAX], ///Length
    a[NMAX]; ///Ancestor

bool cmp(PII a, PII b) {
    if(a.val==b.val)
        return a.poz < b.poz;
    return a.val < b.val;
}

int cbin(int val, int index, int n) {
    int m, first, last, ans;

    first = 0;
    last  = 0;
    ans   = 0;

    for(m=MB; m; m>>=1)
        if((last|m)<=n && v[last|m].val<val)
            last|=m;
    for(m=MB; m; m>>=1)
        if((first|m)<=n && v[first|m].val<v[last].val)
            first|=m;
    ++first;

    if(v[first].poz<index) {
        for(m=MB; m; m>>=1)
            if(first+(ans|m)<=last && v[first+(ans|m)].poz<index)
                ans|=m;

        return ans + first;
    }
    else {
        return -1;
    }
}

int main(void) {
    FILE *fi = fopen("secv.in", "r");
    FILE *fo = fopen("secv.out", "w");
    int ans, n;
    int poz, first, last;

    fscanf(fi,"%d",&n);

    for(int i=1; i<=n; ++i) {
        fscanf(fi,"%d",&v[i].val);
        v[i].poz = i;
    }

    sort(v+1, v+1+n, cmp);

    first = v[1].val;
    last  = v[n].val;
    ans   = INF;

    for(int i=1; i<=n; ++i) {
        if(v[i].val == first) {
            l[i] = 1;
            continue;
        }
        if( (poz = cbin(v[i].val, v[i].poz, n)) < 0  || !l[poz] ) { ///Abuzul are consecinte grave
            continue;
        }

        l[i] = l[poz]+v[i].poz-v[poz].poz;
        if(v[i].val == last)
            ans = min(ans, l[i]);
    }

    if(ans==INF) {
        fprintf(fo,"%d\n",-1);
    }
    else {
        fprintf(fo,"%d\n",(n==1)?1:ans);
    }

    fclose(fi);
    fclose(fo);
    return 0;
}