HDU 6703 array(主席树)

http://acm.hdu.edu.cn/showproblem.php?pid=6703

题意

给定一个长度为n的排列(1-n),要你实现操作两种,

1 x:给第x个数加上1e7;

2 x y:查询最小的且不小于y的且不在区间[1,x]里出现过的数。

题解

对权值建主席树,维护区间最小值,插入一个数相当于这个数被ban,进行1操作相当于取消ban,如果真去实现修改会比较麻烦,由于这个序列是一个排列,我们对一些数取消ban相当于答案可以直接出现在这些数里,所以我们可以用set保存一下取消ban的数然后联合查询即可。

 1 #define bug(x) cout<<#x<<" is "<<x<<endl
 2 #define IO std::ios::sync_with_stdio(0)
 3 #include <bits/stdc++.h>
 4 #define iter ::iterator
 5 #define pa pair<int,ll>
 6 using namespace  std;
 7 #define ll long long
 8 #define mk make_pair
 9 #define pb push_back
10 #define se second
11 #define fi first
12 ll mod=998244353;
13 const int N=1e5+50;
14 int a[N],rt[N],minv[N*20],ls[N*20],rs[N*20];
15 int cnt,tot;
16 void build(int &o,int l,int r){
17     o=++tot;
18     if(l==r){
19         minv[o]=l;
20         return;
21     }
22     int m=(l+r)/2;
23     build(ls[o],l,m);
24     build(rs[o],m+1,r);
25     minv[o]=min(minv[ls[o]],minv[rs[o]]);
26 }
27 void up(int &o,int pre,int l,int r,int p){
28     o=++cnt;
29     ls[o]=ls[pre];
30     rs[o]=rs[pre];
31     if(l==r){
32         minv[o]=1e9;
33         return;
34     }
35     int m=(l+r)/2;
36     if(p<=m)up(ls[o],ls[pre],l,m,p);
37     else up(rs[o],rs[pre],m+1,r,p);
38     minv[o]=min(minv[ls[o]],minv[rs[o]]);
39 }
40 int qu(int o,int l,int r,int ql,int qr){
41     if(l>=ql&&r<=qr){
42         return minv[o];
43     }
44     int m=(l+r)/2;
45     int res=1e9;
46     if(ql<=m)res=min(res,qu(ls[o],l,m,ql,qr));
47     if(qr>m)res=min(res,qu(rs[o],m+1,r,ql,qr));
48     return res;
49 }
50 int T,q,n;
51 int main(){
52     scanf("%d",&T);
53     int h=1e5+1;
54     build(rt[0],1,h);
55     while(T--){
56         scanf("%d%d",&n,&q);
57         cnt=tot;
58         for(int i=1;i<=n;i++){
59             scanf("%d",&a[i]);
60             up(rt[i],rt[i-1],1,h,a[i]);
61         }
62         int t,x,y,ans=0;
63         set<int>s;
64         while(q--){
65             scanf("%d%d",&t,&x);
66             x^=ans;
67             if(t==1)s.insert(a[x]);
68             else{
69                 scanf("%d",&y);
70                 y^=ans;
71                 int res1=qu(rt[x],1,h,y,h);
72                 int res2=1e9;
73                 auto it=s.lower_bound(y);
74                 if(it!=s.end())res2=*it;
75                 ans=min(res1,res2);
76                 printf("%d\n",ans);
77             }
78         }
79     }
80 }

 

posted @ 2019-08-24 21:32  Venux  阅读(311)  评论(0编辑  收藏  举报