zoukankan      html  css  js  c++  java
  • 求最值背景下动态删除线段树节点

    动态最值(minmax.Cpp/c/Java)
    (空间限制128M)

    有一个包含n个元素的数组,要求实现以下操作:
    DELETE k:删除位置k上的数。右边的数往左移一个位置。
    QUERY i j:查询位置i~j上所有数的最小值和最大值。

    【输入】(minmax.in)
    输入第一行包含两个数n, m,表示原始数组的元素个数和操作的个数。第二行包括n个数,表示原始数组。以下m行,每行格式为1 k或者2 i j,其中第一个数为1表示删除操作,为2表示询问操作。
    【输出】(minmax.out)
    输出一行,包括两个数,表示该范围内的最小值和最大值。
    【样例输入】
    10 4
    1 5 2 6 7 4 9 3 1 5
    2 2 8
    1 3
    1 6
    2 2 8
    【样例输出】
    2 9
    1 7
    【限制】
    数组中的元素绝对值均不超过109
    第一组:n = 10, 1 分, 时限 0.1s
    第二组:n = 333, 2 分, 时限 0.1s
    第三组:n = 4232,3分, 时限 0.1s
    第四组:n = 6324, 4分, 时限 0.2s
    第五组:n = 9999, 5分, 时限 2s
    第六组:n = 100000, m = 300000, 10分,时限 2s
    第七组:n = 300000, m = 422342, 13分,时限 3s
    第八组:n = 500000, m = 651222, 18分,时限 3s
    第九组:n = 900000, m = 432122, 22分,时限 5s
    第十组:n = 999999,m = 999999,22分,时限 5s

    删完后左移,我们并不是真的左移,而是线段树节点记录一个num,记录子节点个数,根据这个递归地找删除后的index

    还没对拍的标程如下,(样例可过

     1 #include <stdio.h>
     2 #include <algorithm>
     3 using  namespace std;
     4 
     5 const int maxn=1e5+7;
     6 const int INF=1e9+7;
     7 int mi[maxn],mx[maxn],num[maxn],ls[maxn],rs[maxn],a[maxn],tot,n,m;
     8 void pup(int p){
     9     mi[p]=min(mi[ls[p]],mi[rs[p]]);
    10     mx[p]=max(mx[ls[p]],mx[rs[p]]);
    11     num[p]=num[ls[p]]+num[rs[p]];
    12 }
    13 void build(int p,int l,int r){
    14     if(l==r){mi[p]=mx[p]=a[l];num[p]=1;return ;}//index is p not l
    15     int mid=(l+r)>>1;
    16     build(ls[p]=++tot,l,mid);
    17     build(rs[p]=++tot,mid+1,r);
    18     pup(p);
    19 }
    20 int cnt=0;
    21 int queryMx(int p,int l,int r,int L,int R){
    22     if(l>=r&&r<=R){ //这里不要写反
    23         return mx[p];
    24     }
    25     if(L<=num[ls[p]]&&R>num[ls[p]]){
    26         return max(queryMx(ls[p],1,num[ls[p]],L,num[ls[p]]),queryMx(rs[p],1,num[rs[p]],1,R-num[ls[p]]));
    27     }
    28     else if(L<=num[ls[p]]){
    29         return queryMx(ls[p],1,num[ls[p]],L,R);
    30     }
    31     else{
    32         return queryMx(rs[p],1,num[rs[p]],L-num[ls[p]],R-num[ls[p]]);
    33     }
    34 }
    35 int queryMi(int p,int l,int r,int L,int R){
    36     if(l>=L&&r<=R){
    37         return mi[p];
    38     }
    39     if(L<=num[ls[p]]&&R>num[ls[p]]){
    40         return min(queryMi(ls[p],1,num[ls[p]],L,num[ls[p]]),queryMi(rs[p],1,num[rs[p]],1,R-num[ls[p]]));
    41     }
    42     else if(L<=num[ls[p]]){
    43         return queryMi(ls[p],1,num[ls[p]],L,R);
    44     }
    45     else{
    46         return queryMi(rs[p],1,num[rs[p]],L-num[ls[p]],R-num[ls[p]]);
    47     }
    48 }
    49 void Delete(int p,int l,int r,int x){
    50     if(l==r){
    51         mi[p]=INF;
    52         mx[p]=-INF;
    53         num[p]=0;
    54         return ;
    55     }
    56     if(x<=num[ls[p]]) Delete(ls[p],1,num[ls[p]],x);
    57     else         Delete(rs[p],1,num[rs[p]],x-num[ls[p]]); //由于删除后所有数都向左移动,所以我们也得递归找位置删除
    58     pup(p);
    59 }
    60 int main(){
    61     scanf("%d%d",&n,&m);
    62     for(int i=1;i<=n;++i) scanf("%d",a+i);
    63     int op,l,r,x;
    64     tot=1;build(1,1,n);
    65     for(int i=1;i<=m;++i){
    66         scanf("%d",&op);
    67         if(op==1){
    68             scanf("%d",&x);
    69             Delete(1,1,num[1],x);
    70         }
    71         else{
    72             scanf("%d%d",&l,&r);
    73             printf("%d %d
    ",queryMi(1,1,num[1],l,r),queryMx(1,1,num[1],l,r));
    74         }
    75     }
    76     return 0;
    77 }
  • 相关阅读:
    Jmeter逻辑控制器
    python学习笔记——%占位符的使用
    python学习笔记——生成随机数
    python学习笔记——变量的规则
    loadrunner11中HTTP/HTML的HTML-base script的两种script type有什么区别?
    loadrunner11如何实时查看脚本的运行情况?
    loaderunner11回放脚本时如何设置【运行时行为】?
    appium学习笔记之——popupwindow控件元素无法定位
    Chrome、Firefox、IE等浏览器驱动diver程序存放目录
    npm方式安装appium环境所遇到的各种问题
  • 原文地址:https://www.cnblogs.com/linkzijun/p/6957056.html
Copyright © 2011-2022 走看看