You are given an array a1,a2,...,an(∀i∈[1,n],1≤ai≤n). Initially, each element of the array is unique.c++
Moreover, there are m instructions.数组
Each instruction is in one of the following two formats:promise
Please print all results of the instructions in format 2.less
The first line of the input contains an integer T(1≤T≤10), denoting the number of test cases.ui
In each test case, there are two integers n(1≤n≤100,000),m(1≤m≤100,000) in the first line, denoting the size of array a and the number of instructions.spa
In the second line, there are n distinct integers a1,a2,...,an (∀i∈[1,n],1≤ai≤n),denoting the array.
For the following m lines, each line is of format (1,t1) or (2,t2,t3).
The parameters of each instruction are generated by such way :code
For instructions in format 1 , we defined pos=t1⊕LastAns . (It is promised that 1≤pos≤n)orm
For instructions in format 2 , we defined r=t2⊕LastAns,k=t3⊕LastAns. (It is promised that 1≤r≤n,1≤k≤n )ip
(Note that ⊕ means the bitwise XOR operator. )element
Before the first instruction of each test case, LastAns is equal to 0 .After each instruction in format 2, LastAns will be changed to the result of that instruction.
(∑n≤510,000,∑m≤510,000 )
For each instruction in format 2, output the answer in one line.
Sample Input
3 5 9 4 3 1 2 5 2 1 1 2 2 2 2 6 7 2 1 3 2 6 3 2 0 4 1 5 2 3 7 2 4 3 10 6 1 2 4 6 3 5 9 10 7 8 2 7 2 1 2 2 0 5 2 11 10 1 3 2 3 2 10 10 9 7 5 3 4 10 6 2 1 8 1 10 2 8 9 1 12 2 15 15 1 12 2 1 3 1 9 1 12 2 2 2 1 9
1 5 2 2 5 6 1 6 7 3 11 10 11 4 8 11
首先理解对题意...题意给了两种操做,一种是将位于pos的数变成\(a_{pos}+10000000\),另外一种是询问不等于\([1,r]\)中的任何一个数的,而且大于等于k的最小的数。也就是说这个询问的答案不必定是数组中的数。
由于题中给了限制,一开始数组中的数都知足\(1<=a_i<=n\),且值各不相同,因此一旦进行1操做,这个数就能够被任何答案包含了,那咱们就直接维护权值为下标,出现的位置为值得线段树,每次修改就是单点修改,将\(a_{pos}\)的值修改成n+1,询问就是查询区间[k,n+1]内,第一个值大于r的下标,直接利用线段树的二分性查找便可
#include <bits/stdc++.h> #define lson (o << 1) #define rson (o << 1 | 1) using namespace std; const int N = 1e5 + 50; int a[N], pos[N]; int maxv[N << 2]; int n, m; void pushup(int o) { maxv[o] = max(maxv[lson], maxv[rson]); } void build(int o, int l, int r) { if (l == r) { maxv[o] = pos[l]; return; } int mid = (l + r) >> 1; build(lson, l, mid); build(rson, mid + 1, r); pushup(o); } int query(int o, int l, int r, int ql, int qr, int v) { if (ql > qr) return n + 1; if (l == r) { if (maxv[o] >= v) { return l; } else return n + 1; } if (ql <= l && r <= qr) { if (maxv[o] < v) return n + 1; } int mid = (l + r) >> 1; if (qr <= mid) return query(lson, l, mid, ql, qr, v); else if (ql > mid) return query(rson, mid + 1, r, ql, qr, v); else { int x = query(lson, l, mid, ql, mid, v); if (x != n + 1) return x; return query(rson, mid + 1, r, mid + 1, qr, v); } } void update(int o, int l, int r, int pos) { if (l == r) { maxv[o] = n + 1; return; } int mid = (l + r) >> 1; if (pos <= mid) update(lson, l, mid, pos); else update(rson, mid + 1, r, pos); pushup(o); } int main() { int t; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); pos[a[i]] = i; } pos[n + 1] = n + 1; build(1, 1, n + 1); int ans = 0; for (int i = 1; i <= m; i++) { int t; scanf("%d", &t); if (t == 2) { int r, k; scanf("%d%d", &r, &k); r ^= ans, k ^= ans; printf("%d\n", ans = query(1, 1, n + 1, k, n + 1, r + 1)); } if (t == 1) { int x; scanf("%d", &x); x ^= ans; update(1, 1, n + 1, a[x]); } } } return 0; }