主席树维护最小值
如果一个数被插入队列,相当于这个数无法被选 inf
如果一个数加1e7;相当于这个数又可以被选
实际维护+1e7的操作比较麻烦
直接用将+1e7的数字压入set中二分找>=k的最小的数在于查找的答案去min
#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<bitset>
#define inf 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define sd(x) scanf("%d",&(x))
#define sl(x) scanf("%lld",&(x))
#define slf(x) scanf("%lf",&(x))
#define scs(s) scanf("%s",s)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define lowbit(x) x&(-x)
#define ls now<<1
#define rs now<<1|1
#define lson l,mid,ls
#define rson mid+1,r,rs
#define All L,R
using namespace std;
const int maxn=5e5+10;
struct Node{
int l,r,s;
}tree[maxn*32];
int a[maxn];
int root[maxn],Min[maxn*32];
int n,m,tot=0,k=0;
int built(int l,int r)
{
int mid=(l+r)>>1;
int now=++k;
if(l==r)
{
Min[now]=l;
return now;
}
tree[now].l=built(l,mid);
tree[now].r=built(mid+1,r);
Min[now]=min(Min[tree[now].l],Min[tree[now].r]);
return now;
}
int update(int pre,int p,int l,int r)
{
int mid=(l+r)>>1;
int now=++k;
tree[now].l=tree[pre].l;
tree[now].r=tree[pre].r;
if(l==r)
{
Min[now]=1e9;
return now;
}
if(p<=mid)
tree[now].l=update(tree[pre].l,p,l,mid);
else
tree[now].r=update(tree[pre].r,p,mid+1,r);
Min[now]=min(Min[tree[now].l],Min[tree[now].r]);
return now;
}
int query(int now,int l,int r,int L,int R)
{
int mid=(l+r)/2;
if(l>=L&&r<=R){
return Min[now];
}
int ans=1e9;
if(L<=mid)ans=min(ans,query(tree[now].l,l,mid,L,R));
if(R>mid)ans=min(ans,query(tree[now].r,mid+1,r,L,R));
return ans;
}
int main()
{
int t;
int h=1e5+1;
cin>>t;
root[0]=built(1,h);
while(t--)
{
int last=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
root[i]=update(root[i-1],a[i],1,h);
}
set<int>s;
while(m--)
{
int cmd,t1,t2,t3;
sd(cmd);
if(cmd==1)
{
sd(t1);
t1^=last;
s.insert(a[t1]);
}
else
{
sd(t2),sd(t3);
t2^=last;
t3^=last;
int a1=query(root[t2],1,h,t3,h);
int a2=1e9;
auto it=s.lower_bound(t3);
if(it!=s.end()) a2=*it;
last=min(a1,a2);
cout<<last<<"\n";
}
}
}
return 0;
}