Cod sursa(job #2743105)

Utilizator YouDontNeedMyNameJurcut Paul YouDontNeedMyName Data 22 aprilie 2021 16:08:28
Problema Pq Scor 0
Compilator cpp-64 Status done
Runda acm_2017_ubb4 Marime 3.08 kb
#include <bits/stdc++.h>
#define nmax 100005
using namespace std;

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

const int bucket_size = 700;
int idx[nmax],v[nmax],ap[nmax],first[nmax],last[nmax],previous[nmax],next_elem[nmax],rez[nmax];
multiset<int, greater<int> > itv;
pair<int,int> interval[nmax];

bool comp(int st, int dr){
    int st_bucket = interval[st].first/bucket_size;
    int dr_bucket = interval[dr].first/bucket_size;
    if(st_bucket == dr_bucket){
        if(st_bucket%2){
            return interval[st].second > interval[dr].second;
        }
        else{
            return interval[st].second < interval[dr].second;
        }
    }
    return st_bucket < dr_bucket;
}

int main(){
    int n,q;
    in >> n >> q;
    for(int i=1; i<=n; i++){
        in >> v[i];
    }
    for(int i=1; i<=n; i++){
        if(ap[v[i]]){
            previous[i] = ap[v[i]];
        }
        ap[v[i]] = i;
    }
    memset(ap, 0, sizeof(ap));
    for(int i=n; i>=1; i--){
        if(ap[v[i]]){
            next_elem[i] = ap[v[i]];
        }
        ap[v[i]] = i;
    }
    for(int i=0; i<q; i++){
        in >> interval[i].first >> interval[i].second;
        idx[i] = i;
    }
    sort(idx, idx+q, comp);
    for(int a = interval[0].first; a<=interval[0].second; a++){
        if(last[v[a]]){
            itv.insert(a-last[v[a]]);
        }
        else{
            first[v[a]] = a;
        }
        last[v[a]] = a;
    }
    int cura = interval[0].first, curb = interval[0].second;
    if(itv.size() == 0){
        rez[idx[0]] = -1;
    }
    else{
        auto best = itv.begin();
        rez[idx[0]] = *best;
    }
    for(int i=1; i<q; i++){
        int a = interval[idx[i]].first;
        int b = interval[idx[i]].second;
        while(curb < b){
            curb++;
            if(last[v[curb]]){
                itv.insert(curb-last[v[curb]]);
            }
            else{
                first[v[curb]] = curb;
            }
            last[v[curb]] = curb;
        }
        while(cura > a){
            cura--;
            if(first[v[cura]]){
                itv.insert(cura - first[v[cura]]);
            }
            else{
                last[v[cura]] = cura;
            }
            first[v[cura]] = cura;
        }
        while(curb > b){
            if(previous[curb] >= cura && previous[curb]){
                auto elem = itv.find(curb - previous[curb]);
                if(elem != itv.end()){
                    itv.erase(elem);   
                }
            }
            last[v[curb]] = previous[curb];
            curb--;
        }
        while(cura < a){
            if(next_elem[cura] <= curb && next_elem[cura]){
                auto elem = itv.find(next_elem[cura] - cura);
                if(elem != itv.end()){
                    itv.erase(elem);   
                }
            }
            first[v[cura]] = next_elem[cura];
            cura++;
        }
        if(itv.size() == 0){
            rez[idx[i]] = -1;
        }
        else{
            auto elem = itv.begin();
            rez[idx[i]] = *elem;
        }
    }
    for(int i=0; i<q; i++){
        out << rez[i] << '\n';
    }
    return 0;
}