Cod sursa(job #1700960)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 11 mai 2016 21:16:48
Problema Secv Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.71 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, prev, ans;

    first = 0;
    last  = 0;
    prev  = 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]);
    }

    fprintf(fo,"%d\n",ans);

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