题意:
给定一个
1...
n
1...n
1...n的一个排列,有两种操作
- 给 a i a_i ai加上 1000000 1000000 1000000
- 查询不存在于
a
1
,
.
.
a
r
a_1,..a_r
a1,..ar中的大于
k
k
k的最大值
强制在线
分析:
换一个方向,就是查询大于等于
k
k
k的第一个不在
a
1
,
.
.
.
a
r
a_1,...a_r
a1,...ar的数
我们可以维护
1..
n
,
n
+
1
1..n,n+1
1..n,n+1的位置,查询
[
k
,
n
+
1
]
[k,n+1]
[k,n+1]的第一个大于
r
r
r的,先查询左边,如果存在就返回即可。
#include <bits/stdc++.h>
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define me(ar) memset(ar,0,sizeof(ar))
#define lowbit(x) (x&(-x))
#define Pb push_back
#define FI first
#define SE second
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define IOS ios::sync_with_stdio(false)
#define DEBUG cout<<endl<<"DEBUG"<<endl;
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int prime = 999983;
const int INF = 0x7FFFFFFF;
const LL INFF = 0x7FFFFFFFFFFFFFFF;
const double pi = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-6;
const LL mod = 1e9 + 7;
LL qpow(LL a, LL b) {LL s = 1; while (b > 0) {if (b & 1)s = s * a % mod; a = a * a % mod; b >>= 1;} return s;}
LL gcd(LL a, LL b) {return b ? gcd(b, a % b) : a;}
int dr[2][4] = {1, -1, 0, 0, 0, 0, -1, 1};
typedef pair<int, int> P;
const int maxn = 1e5 + 10;
int a[maxn];
int n, m;
#define lson (o<<1)
#define rson (o<<1|1)
int tree[maxn << 2];
void pushup(int o) {
tree[o] = max(tree[lson], tree[rson]);
}
void Build(int o, int l, int r) {
if (l == r) {
tree[o] = a[l];
return ;
}
int mid = (l + r) >> 1;
Build(lson, l, mid);
Build(rson, mid + 1, r);
pushup(o);
}
void update(int o, int l, int r, int x) {
if (l == r) {
tree[o] = n + 1;
return ;
}
int mid = (l + r) >> 1;
if (x <= mid)
update(lson, l, mid, x);
else
update(rson, mid + 1, r, x);
pushup(o);
}
int query(int o, int l, int r, int L, int t) {
// cout << l << " " << r << " " << L << " " << tree[o] << " " << t << endl;
if (tree[o] <= t) return n + 1;
if (l == r) {
if (tree[o] > t) return l;
else
return n + 1;
}
int mid = (l + r) >> 1;
int ans = n + 1;
if (L <= mid) {
ans = min(ans, query(lson, l, mid, L, t));
}
if (ans < n + 1) return ans;
return query(rson, mid + 1, r, L, t);
}
int now[maxn];
namespace io {
const int L = 1 << 20 | 1;
char ibuf[L], *iS, *iT, c, obuf[L], *oS = obuf, *oT = obuf + L - 1, qu[55]; int f, qr;
#ifdef whzzt
#define gc() getchar()
#else
#define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, L, stdin), iS == iT ? EOF : *iS ++) : *iS ++)
#endif
template <class I>
inline void gi (I &x) {
for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;
for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15); x *= f;
}
inline void flush () {
fwrite (obuf, 1, oS - obuf, stdout);
}
inline void putc (char x) {
*oS ++ = x;
if (oS == oT) flush (), oS = obuf;
}
template <class I>
void print (I x) {
if (!x) putc ('0'); if (x < 0) putc ('-'), x = -x;
while (x) qu[++ qr] = x % 10 + '0', x /= 10;
while (qr) putc (qu[qr --]);
}
struct io_ff { ~io_ff() { flush(); } } _io_ff_;
}
using io :: gi;
using io :: putc;
using io :: print;
int main(void)
{
// freopen("E.cpp", "r", stdin);
int T;
// cin >> T;
gi(T);
while (T--) {
// scanf("%d%d", &n, &m);
gi(n), gi(m);
for (int i = 1; i <= n; ++i) {
int t;
// scanf("%d", &t);
gi(t);
now[i] = t;
a[t] = i;
}
a[n + 1] = n + 1;
Build(1, 1, n + 1);
int ans = 0;
while (m--) {
int op, t1, t2;//, t3;
// scanf("%d", &op);
gi(op);
if (op == 1) {
// scanf("%d", &t1);
gi(t1);
t1 ^= ans;
// cout << t1 << " " << now[t1] << endl;
update(1, 1, n + 1, now[t1]);
}
else {
// scanf("%d%d", &t1, &t2);
gi(t1), gi(t2);
int r = t1 ^ ans;
int k = t2 ^ ans;
printf("%d\n", ans = query(1, 1, n + 1, k, r));
}
}
}
return 0;
}