http://acm.hdu.edu.cn/showproblem.php?pid=6703
大意:给一个n个元素的数组,其中所有元素都是不重复的[1,n]。
两种操作:
将pos位置元素+1e7
查询不属于[1,r]中的最小的>=k的值
思路:将数组元素排序,根据其下标建立权值线段树,维护下标的最大值。
修改将对应值在线段树中的下标直接改为inf32。
查询时,查[k,n+1]区间内找到第一个下标>r的位置。
#include<bits/stdc++.h> #define ll long long #define PII pair<int,int> #define PLL pair<ll,ll> #define clean(a,b) memset(a,b,sizeof(a)) using namespace std; const int MAXN=1e5+10; const int INF32=0x3f3f3f3f; const ll INF64=0x3f3f3f3f3f3f3f3f; const ll MOD=1e9+7; const double PI=acos(-1.0); const double EPS=1.0e-8; struct segTree{ struct node{ int l,r,len,id,mx; }tree[MAXN<<2]; void pushup(int rt){ tree[rt].mx = max(tree[rt<<1].mx,tree[rt<<1|1].mx); } void build(int l,int r,int rt,int A[]){ tree[rt].l=l;tree[rt].r=r;tree[rt].len=r-l+1; if(l==r){ tree[rt].id = tree[rt].mx = A[l]; return; } int mid = (l+r)>>1; build(l,mid,rt<<1,A); build(mid+1,r,rt<<1|1,A); pushup(rt); } void update(int pos,int val,int rt){ if(tree[rt].l==tree[rt].r){ tree[rt].id = tree[rt].mx = val; return; } if(pos<=tree[rt<<1].r) update(pos,val,rt<<1); else update(pos,val,rt<<1|1); pushup(rt); } int query(int ql,int qr,int val,int rt){ if(tree[rt].l==tree[rt].r) return tree[rt].l; int ans = INF32; if(ql<=tree[rt<<1].r&&val<tree[rt<<1].mx) ans=query(ql,qr,val,rt<<1); if(ans!=INF32) return ans; if(qr>=tree[rt<<1|1].l&&val<tree[rt<<1|1].mx) ans=query(ql,qr,val,rt<<1|1); return ans; } }; segTree seg; PII A[MAXN]; int B[MAXN]; int n,m; int cmp1(PII a,PII b){ return a.second<b.second; } int main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int t; cin>>t; while(t--){ cin>>n>>m; for(int i=1;i<=n;i++){ cin>>A[i].first; A[i].second = i; } sort(A+1,A+1+n); for(int i=1;i<=n;i++){ B[i] = A[i].second; } sort(A+1,A+1+n,cmp1); B[++n] = INF32; seg.build(1,n,1,B); int ans = 0; while(m--){ int opt; cin>>opt; if(opt==1){ int t1,pos; cin>>t1; pos = t1^ans; seg.update(A[pos].first,INF32,1); } else { int t2,t3,r,k; cin>>t2>>t3; r = t2^ans; k = t3^ans; cout<<(ans=seg.query(k,n,r,1))<<endl; } } } return 0; }