Pagini recente » Cod sursa (job #988766) | Cod sursa (job #197775) | Cod sursa (job #2732744) | Cod sursa (job #622657) | Cod sursa (job #2887358)
#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;
}