• 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
    ",ans);
    77             }
    78         }
    79     }
    80 }
  • 相关阅读:
    依次逐个亮灯并且每次只能亮一个灯的跑马灯程序
    逐个点亮LED灯,再逐个熄灭LED灯的跑马灯程序---基于74HC595移位锁存器,程序框架用switch语句
    把74HC595驱动程序翻译成类似单片机IO口直接驱动的方式
    两片联级74HC595驱动16个LED灯的基本驱动程序
    树莓派
    Linux I2C驱动
    转:使用 /proc 文件系统来访问 Linux 内核的内容
    转: 使用 /sys 文件系统访问 Linux 内核
    树梅派 -- 通过/sys读写ADC芯片 pcf8591
    树莓派 -- oled 续(2) python
  • 原文地址:https://www.cnblogs.com/ccsu-kid/p/11406177.html
Copyright © 2020-2023  润新知