Cod sursa(job #1709443)

Utilizator oldscotchUPB Old Scotch oldscotch Data 28 mai 2016 12:18:44
Problema Pq Scor 100
Compilator cpp Status done
Runda ONIS 2016 - Runda - 2 - ACM ICPC Romanian Programming Contest Marime 2.57 kb
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

const int NMAX = 100505;
const int LMAX = (1 << 18);
const int INF = 0x3f3f3f3f;

struct query
{
    int to, idx;
};
int N, M, A[NMAX], val[NMAX], sol[NMAX];

vector<int> pos[NMAX];
vector<query> Q[NMAX];

int arb[LMAX];

void read()
{
    scanf("%d%d", &N, &M);
    for (int i = 1; i <= N; i++)
    {
        scanf("%d", &A[i]);
        pos[A[i]].push_back(i);
    }

    int from, to;
    for (int i = 1; i <= M; i++)
    {
        scanf("%d%d", &from, &to);
        Q[from].push_back({to, i});
    }
}

void cstr(int left, int right, int node)
{
    if (left == right)
    {
        arb[node] = val[left];
        return ;
    }
    int mid = (left + right) >> 1;
    cstr(left, mid, node * 2);
    cstr(mid + 1, right, node * 2 + 1);
    arb[node] = max(arb[node * 2], arb[node * 2 + 1]);
}

void update(int left, int right, int node, int pos, int val)
{
    if (left == right)
    {
        arb[node] = val;
        return ;
    }
    int mid = (left + right) >> 1;
    if (pos <= mid)
    {
        update(left, mid, node * 2, pos, val);
    }
    else
    {
        update(mid + 1, right, node * 2 + 1, pos, val);
    }

    arb[node] = max(arb[node * 2], arb[node * 2 + 1]);
}

int get(int left, int right, int node, int l, int r)
{
    if (r < left || right < l)
    {
        return -INF;
    }
    if (l <= left && right <= r)
    {
        return arb[node];
    }
    int mid = (left + right) >> 1;
    return max(
               get(left, mid, node * 2, l, r),
               get(mid + 1, right, node * 2 + 1, l, r));
}

void prepare()
{
    for (int v = 0; v < NMAX; v++)
    {
        if (!pos[v].empty())
        {
            reverse(pos[v].begin(), pos[v].end());
            for (size_t i = 0; i < pos[v].size() - 1; i++)
            {
                val[pos[v][i]] = pos[v][i] - pos[v][i + 1];
            }
        }
    }

    cstr(1, N, 1);
}

void solve()
{
    for (int i = 1; i <= N; i++)
    {
        for (auto& qry: Q[i])
        {
            sol[qry.idx] = get(1, N, 1, i, qry.to);
        }

        // update
        pos[A[i]].pop_back();
        if (!pos[A[i]].empty())
        {
            update(1, N, 1, pos[A[i]].back(), 0);
        }
    }

    for (int i = 1; i <= M; i++)
    {
        printf("%d\n", sol[i] ? sol[i] : -1);
    }
}

int main()
{
    freopen("pq.in", "r", stdin);
    freopen("pq.out", "w", stdout);

    read();
    prepare();
    solve();

    return 0;
}