Cod sursa(job #2887358)

Utilizator ArdeleanOficialAlexandru ArdeleanOficial Data 9 aprilie 2022 14:01:40
Problema A+B Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.79 kb
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>

using namespace std;

#define DEBUG

const int B = 707, N = 5e5 + 7, Q = 5e5 + 7, INF = 1e9 + 7;

int v[N], ras[Q];
vector < int > bucket[N / B + 7];
unordered_map < int, int > st, dr;
vector < pair < int, int > > query;

///SOL:
/// Mo fara adaugari, doar scoateri
/// cand ceva se scoate(adauga), obtinem solutii posibile noi
/// se poate si fara long, folosing unordered map

vector < int > ans; ///pentru undo-uri, ne trebuie ans trecute

vector < pair < int, pair < int, int > > > undo;

void addst(int ind) {
    if (st.find(v[ind]) != st.end())
        undo.push_back({0, {v[ind], st[v[ind]]}});
    else
        undo.push_back({0, {v[ind], 0}});
    st[v[ind]] = ind;
    if (dr.find(v[ind]) != dr.end())
        ans.push_back(min(ans.back(), dr[v[ind]] - ind));
    else
        ans.push_back(ans.back());
}

void adddr(int ind) {
    if (dr.find(v[ind]) != dr.end())
        undo.push_back({1, {v[ind], dr[v[ind]]}});
    else
        undo.push_back({1, {v[ind], 0}});
    dr[v[ind]] = ind;
    if (st.find(v[ind]) != st.end())
        ans.push_back(min(ans.back(), ind - st[v[ind]]));
    else
        ans.push_back(ans.back());
}

void undo_mo() {
    #ifdef DEBUG
    cout << "START\n";
    for (int i : ans)
        cout << i << ' ';
    cout << '\n';
    for (auto i : undo)
        cout << i.first << ' ' << i.second.first << ' ' << i.second.second << '\n';
    cout << "STOP\n";
    #endif // DEBUG
    ans.pop_back();
    if (undo.back().first) {
        if (undo.back().second.second)
            dr[undo.back().second.first] = dr[undo.back().second.second];
        else
            dr.erase(undo.back().second.first);
    }
    else {
        if (undo.back().second.second)
            st[undo.back().second.first] = st[undo.back().second.second];
        else
            st.erase(undo.back().second.first);
    }
    undo.pop_back();
}

int main()
{
    int n, q;
    cin >> n;
    for (int i = 1; i <= n; ++i)
        cin >> v[i], v[i] ^= v[i - 1];
    cin >> q;
    query.push_back({0, 0});
    for (int i = 1; i <= q; ++i) {
        int a, b;
        cin >> a >> b;
        a++;
        b++;
        bucket[a / B].push_back(query.size());
        query.push_back({a, b});
    }
    #ifdef DEBUG
    for (int i = 1; i <= n; ++i)
        cout << v[i] << " \n"[i == n];
    #endif // DEBUG
    for (int b = 0; b <= n / B; ++b) {
        ans.clear();
        st.clear();
        dr.clear();
        ans.push_back(INF);
        sort(bucket[b].rbegin(), bucket[b].rend(), [&] (int a, int b) {
                return query[a].second < query[b].second;
             });
        #ifdef DEBUG
        for (int i : bucket[b])
            cout << '(' << query[i].first << ' ' << query[i].second << "), ";
        cout << '\n';
        #endif // DEBUG
        for (int i = 1; i < B * b; ++i)
            addst(i);
        int l(B * b), r(n);
        for (int i : bucket[b]) {
            while (r >= query[i].second) {
                adddr(r);
                r--;
            }
            while (l < query[i].first) {
                addst(l);
                l++;
            }
    #ifdef DEBUG
    cout << "AAAAAAAAAAAAAAAAA\nSTART\n";
    for (int i : ans)
        cout << i << ' ';
    cout << '\n';
    for (auto i : st)
        cout << "0 " << i.first << ' ' << i.second << '\n';
    for (auto i : dr)
        cout << "1 " << i.first << ' ' << i.second << '\n';

    cout << "STOP\n";
    #endif // DEBUG
            ras[i] = ans.back();
            while (l > B * b) {
                l--;
                undo_mo();
            }
        }
    }
    for (int i = 1; i <= q; ++i)
        cout << ras[i] << '\n';
    return 0;
}