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 }


  • 相关阅读:
    hdu-2841 Visible Trees---容斥定理
    hdu-4135 Co-prime---容斥定理经典&&求1-m中与n互质的数目
    hdu-1796 How many integers can you find---容斥定理
    hdu-2837 Calculation---指数循环节
    FZU-1759 Super A^B mod C---欧拉降幂&指数循环节
    指数循环节&欧拉降幂
    hdu-3074 Multiply game---线段树+单点更新
    hdu-1792 A New Change Problem---数论&剩余系
    POJ-2429 GCD & LCM Inverse---给出gcd和lcm求原来两个数
    hdu-2685 I won't tell you this is about number theory---gcd和快速幂的性质
  • 原文地址:https://www.cnblogs.com/coded-ream/p/7207921.html
Copyright © 2011-2022 走看看