zoukankan      html  css  js  c++  java
  • 值域线段树 (玲珑OJ 1117)

    点击打开题目链接

    题目意思很简单:

    1、插入x
    2、把小于x的数变成x
    3、把大于x的数变成x
    4、求集合中第x小数
    5、求集合中小于x的数个数


    思路: 线段树,节点是值的分数,你可以离散,也可以不离散,直接标记;我的写法是:   看代码注释>>>


    据说数组改为指针会快点;代码比较挫.存一个;

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <vector>
      5 #include <iostream>
      6 using namespace std;
      7 
      8 typedef long long int LL;
      9 const LL INF=1000000000;
     10 const int maxn=6e6+100;
     11 
     12 
     13 struct ACM
     14 {
     15     struct segment
     16     {
     17         int val,lson,rson;
     18         bool mark;
     19     } seg[maxn];
     20     int sz;
     21     /***
     22         开辟新的节点并初始化
     23     */
     24     int newnode()
     25     {
     26         sz++;
     27         if(sz>=maxn)
     28         {
     29             int lzq=5,zhangpan=0;
     30             lzq=lzq/zhangpan;
     31 
     32         }
     33         seg[sz].lson=seg[sz].rson=-1;
     34         seg[sz].val=0,seg[sz].mark=false;
     35         return sz;
     36     }
     37     /***
     38         初始化根节点
     39     */
     40     void init(int& root)
     41     {
     42         sz=-1;
     43         root=newnode();
     44     }
     45     /***
     46         标记下放操作,如果没有节点开辟新的节点;
     47     */
     48     void pushdown(int i) 
     49     {
     50         int l=seg[i].lson,r=seg[i].rson;
     51         if(l==-1) seg[i].lson=newnode();
     52         if(r==-1) seg[i].rson=newnode();
     53         if(seg[i].mark)
     54         {
     55             seg[i].mark=false;
     56             seg[l].mark=seg[r].mark=true;
     57             seg[l].val=seg[r].val=0;
     58         }
     59     }
     60     void pushup(int i)
     61     {
     62         int l=seg[i].lson,r=seg[i].rson;
     63         seg[i].val=seg[l].val+seg[r].val;
     64     }
     65     /***
     66         插入函数 ; 在 pos 位置上面加上 val;
     67     */
     68     void ins(int i,int l,int r,int pos,int val)
     69     {
     70         if(l==r)
     71         {
     72             seg[i].val+=val;
     73             return ;
     74         }
     75         pushdown(i);
     76         int mid=(l+r)>>1;
     77         if(pos<=mid) ins(seg[i].lson,l,mid,pos,val);
     78         else ins(seg[i].rson,mid+1,r,pos,val);
     79         pushup(i);
     80     }
     81     /***
     82         将 L,R 这段区间上的值,更新为 0;
     83     */
     84     void del(int i,int l,int r,int L,int R)
     85     {
     86         if(l==L&&r==R)
     87         {
     88             seg[i].val=0;
     89             seg[i].mark=true;
     90             return ;
     91         }
     92         pushdown(i);
     93         int mid=(l+r)>>1;
     94         if(R<=mid) del(seg[i].lson,l,mid,L,R);
     95         else if(L>mid) del(seg[i].rson,mid+1,r,L,R);
     96         else del(seg[i].lson,l,mid,L,mid),del(seg[i].rson,mid+1,r,mid+1,R);
     97         pushup(i);
     98     }
     99     int find(int i,int l,int r,int x) //第x小的数字;
    100     {
    101         if(l==r) return l;
    102         pushdown(i);
    103         int lval=0;
    104         int mid=(l+r)>>1;
    105         if(seg[i].lson!=-1) lval=seg[seg[i].lson].val;
    106         if(x<=lval) return find(seg[i].lson,l,mid,x);
    107         else return find(seg[i].rson,mid+1,r,x-lval);
    108     }
    109     int query(int i,int l,int r,int L,int R) //区间 数的个数;
    110     {
    111         if(l==L&&r==R) return seg[i].val;
    112         pushdown(i);
    113         int mid=(l+r)>>1;
    114         if(R<=mid) return query(seg[i].lson,l,mid,L,R);
    115         else if(L>mid) return query(seg[i].rson,mid+1,r,L,R);
    116         else return query(seg[i].lson,l,mid,L,mid)+query(seg[i].rson,mid+1,r,mid+1,R);
    117     }
    118 } AC;
    119 
    120 
    121 
    122 int main()
    123 {
    124     int m;
    125     scanf("%d",&m);
    126     int op,x,root,temp;
    127     AC.init(root);
    128     while(m--)
    129     {
    130         scanf("%d%d",&op,&x);
    131         switch(op)
    132         {
    133         case 1:
    134             AC.ins(root,0,INF,x,1);
    135             break;
    136         case 2:
    137             temp=AC.query(root,0,INF,0,x);
    138             AC.del(root,0,INF,0,x);
    139             AC.ins(root,0,INF,x,temp);
    140             break;
    141         case 3:
    142             temp=AC.query(root,0,INF,x,INF);
    143             AC.del(root,0,INF,x,INF);
    144             AC.ins(root,0,INF,x,temp);
    145             break;
    146         case 4:
    147             printf("%d
    ",AC.find(root,0,INF,x));
    148             break;
    149         case 5:
    150             printf("%d
    ",AC.query(root,0,INF,0,x-1));
    151             break;
    152         }
    153     }
    154     return 0;
    155 }
    
    
    

    代码二:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <vector>
      5 #include <iostream>
      6 using namespace std;
      7 
      8 const int INF=1000000000;
      9 const int maxn=6e6+100;
     10 struct ACM
     11 {
     12     /***
     13         对于 2,3 操作,先查询个数,再插入这个数字:
     14         意思就是更新到底部,加上查询出来的个数;
     15         并加上清零的标记;
     16         
     17     */
     18     struct Node
     19     {
     20         int val,lson,rson;
     21         bool mark;
     22     } seg[maxn];
     23     int sz;
     24     int newnode()
     25     {
     26         sz++;
     27         seg[sz].val=0;
     28         seg[sz].lson=-1;
     29         seg[sz].rson=-1;
     30         seg[sz].mark=false;
     31         return sz;
     32     }
     33     void init(int& root)
     34     {
     35         sz=-1;
     36         root=newnode();
     37     }
     38     void pushdown(int i)
     39     {
     40         int l=seg[i].lson,r=seg[i].rson;
     41         if(l==-1) seg[i].lson=newnode();
     42         if(r==-1) seg[i].rson=newnode();
     43         if(seg[i].mark)
     44         {
     45             seg[i].mark=false;
     46             seg[l].mark=seg[r].mark=true;
     47             seg[l].val=seg[r].val=0;
     48         }
     49     }
     50     void pushup(int i)
     51     {
     52         int l=seg[i].lson,r=seg[i].rson;
     53         seg[i].val=seg[l].val+seg[r].val;
     54     }
     55     int query(int i,int l,int r,int L,int R) //区间 数的个数;
     56     {
     57         if(l==L&&r==R) return seg[i].val;
     58         pushdown(i);
     59         int mid=(l+r)>>1;
     60         if(R<=mid) return query(seg[i].lson,l,mid,L,R);
     61         else if(L>mid) return query(seg[i].rson,mid+1,r,L,R);
     62         else return query(seg[i].lson,l,mid,L,mid)+query(seg[i].rson,mid+1,r,mid+1,R);
     63     }
     64     void ins(int i,int l,int r,int pos,int val)
     65     {
     66         if(l==r)
     67         {
     68             seg[i].val+=val;
     69             return ;
     70         }
     71         pushdown(i);
     72         int mid=(l+r)>>1;
     73         if(pos<=mid) ins(seg[i].lson,l,mid,pos,val);
     74         else ins(seg[i].rson,mid+1,r,pos,val);
     75         pushup(i);
     76     }
     77     void operator2(int i,int l,int r,int x,int val)
     78     {
     79         if(l==r)
     80         {
     81             seg[i].val=val;
     82             return ;
     83         }
     84         int mid=(l+r)>>1;
     85         pushdown(i);
     86         if(x<=mid) operator2(seg[i].lson ,l,mid,x,val);
     87         else
     88         {
     89             seg[seg[i].lson].mark=true;
     90             seg[seg[i].lson].val=0;//如果,存在加到某一边,不存在也需要开新的节点!!
     91             operator2(seg[i].rson,mid+1,r,x,val);
     92         }
     93         pushup(i);
     94     }
     95     void operator3(int i,int l,int r,int x,int val)
     96     {
     97         if(l==r)
     98         {
     99             seg[i].val=val;
    100             return ;
    101         }
    102         pushdown(i);
    103         int mid=(l+r)>>1;
    104         if(x<=mid)
    105         {
    106             seg[seg[i].rson].mark=true;
    107             seg[seg[i].rson].val=0;
    108             operator3(seg[i].lson,l,mid,x,val);
    109         }
    110         else operator3(seg[i].rson,mid+1,r,x,val);
    111         pushup(i);
    112     }
    113     int operator4(int i,int l,int r,int x)
    114     {
    115         if(l==r) return l;
    116         int mid=(l+r)>>1;
    117         pushdown(i);
    118         int val=seg[seg[i].lson].val;
    119         if(x<=val) return operator4(seg[i].lson,l,mid,x);
    120         else return operator4(seg[i].rson,mid+1,r,x-val);
    121     }
    122 } AC;
    123 
    124 
    125 int main()
    126 {
    127 
    128     int m;
    129     while(scanf("%d",&m)!=EOF)
    130     {
    131         int op,x,root,temp;
    132         AC.init(root);
    133         while(m--)
    134         {
    135             scanf("%d%d",&op,&x);
    136             switch(op)
    137             {
    138             case 1:
    139                 AC.ins(root,0,INF,x,1);
    140                 break;
    141             case 2:
    142                 temp=AC.query(root,0,INF,0,x);
    143                 AC.operator2(root,0,INF,x,temp);
    144                 break;
    145             case 3:
    146                 temp=AC.query(root,0,INF,x,INF);
    147                 AC.operator3(root,0,INF,x,temp);
    148                 break;
    149             case 4:
    150                 printf("%d
    ",AC.operator4(root,0,INF,x));
    151                 break;
    152             case 5:
    153                 printf("%d
    ",AC.query(root,0,INF,0,x-1));
    154                 break;
    155             }
    156         }
    157     }
    158     return 0;
    159 }


  • 相关阅读:
    【Azure 应用服务】在Azure App Service多实例的情况下,如何在应用中通过代码获取到实例名(Instance ID)呢?
    【Azure 应用服务】App Service For Windows 中如何设置代理实现前端静态文件和后端Java Spring Boot Jar包
    【Azure Developer】使用Azure Key Vault 的Key签名后,离线验证的一些参考资料
    【Azure Function】调试 VS Code Javascript Function本地不能运行,报错 Value cannot be null. (Parameter 'provider')问题
    【Azure 应用服务】App Service 使用Tomcat运行Java应用,如何设置前端网页缓存的相应参数呢(Xms512m Xmx1204m)?
    【Azure API 管理】APIM添加Logtoeventhub的策略后,一些相关APIM与Event Hub的问题
    【Azure API 管理】为调用APIM的请求启用Trace 调试APIM Policy的利器
    【Azure 事件中心】China Azure上是否有Kafka服务简答
    【Azure 应用服务】探索在Azure上设置禁止任何人访问App Service的默认域名(Default URL)
    【Azure 微服务】记一次错误的更新Service Fabric 证书而引发的集群崩溃而只能重建
  • 原文地址:https://www.cnblogs.com/coded-ream/p/7207921.html
Copyright © 2011-2022 走看看