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; }