https://codeforces.com/contest/1771/problem/F
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define all(a) (a).begin(), (a).end()
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
using namespace std;
const int N = 2e5 + 10;
/*
题意:求一个区间中出现次数为奇数的最小数(强制在线)
解:主席树上二分
用主席数维护区间前缀异或和
若一个区间的中数的数都出现了偶数次, 则他们的异或和为0
但反过来显然不成立
考虑将数组随机映射到一个很大的值域范围中, 考虑前 n - 1 项的异或和, 因为每一项都是随机的,
所以异或和也是随机的, 并且第 n 个数也是随机的, 那么不成立的情况就是两个随机的数字(前n-1项异或和, 第n项)相等
概率为 1/值域
*/
int n, a[N], b[N], rk[N], num[N];
int rt[N], tot;
struct node
{
int ls, rs;
ull xsum;
} tree[N << 5];
void update(int &x, int y, int l, int r, int pos, ull val)
{
x = ++tot;
tree[x] = tree[y];
tree[x].xsum ^= val;
if (l == r)
return;
int mid = (l + r) / 2;
if (pos <= mid)
update(tree[x].ls, tree[y].ls, l, mid, pos, val);
else
update(tree[x].rs, tree[y].rs, mid + 1, r, pos, val);
}
int query(int x, int y, int l, int r)
{
if((tree[x].xsum ^ tree[y].xsum) == 0)
return 0;
if (l == r)
return num[l];
int mid = (l + r) / 2;
if (tree[tree[x].ls].xsum ^ tree[tree[y].ls].xsum)
return query(tree[x].ls, tree[y].ls, l, mid);
else
return query(tree[x].rs, tree[y].rs, mid + 1, r);
}
void solve()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
b[i] = a[i];
}
sort(b + 1, b + 1 + n);
int len = unique(b + 1, b + 1 + n) - b - 1;
for (int i = 1; i <= n; i++)
{
rk[i] = lower_bound(b + 1, b + 1 + len, a[i]) - b;
num[rk[i]] = a[i];
}
std::mt19937_64 rng(std::chrono::steady_clock::now().time_since_epoch().count());
vector<ull> h(len + 1);
for (int i = 1; i <= len; i++)
h[i] = rng();
for (int i = 1; i <= n; i++)
update(rt[i], rt[i - 1], 1, len, rk[i], h[rk[i]]);
int q;
cin >> q;
int ans = 0;
while (q--)
{
int l, r;
cin >> l >> r;
l ^= ans;
r ^= ans;
ans = query(rt[l - 1], rt[r], 1, len);
cout << ans << '\n';
}
}
signed main()
{
IOS;
int t = 1;
// cin >> t;
while (t--)
solve();
return 0;
}