码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 6703 array(主席树)

时间:2019-08-24 23:12:28      阅读:110      评论:0      收藏:0      [点我收藏+]

标签:cout   pair   主席树   fir   out   efi   main   iterator   查询   

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

题意

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

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

2 xy:查询最小的且不小于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 }

 

HDU 6703 array(主席树)

标签:cout   pair   主席树   fir   out   efi   main   iterator   查询   

原文地址:https://www.cnblogs.com/ccsu-kid/p/11406177.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!