zoukankan      html  css  js  c++  java
  • 权值线段树

    权值线段树是什么

    我们一般的线段树的节点下标是数组,而我们只要把它变成值,就能统计每个节点的数量了。  

    类似于桶的实现吧。  

    其实这个的线段树就是前缀和,也可以用树状数组来代替。  

    至于查询k大,只要二分就可以了。  

    数据范围大的时候通常先离散化数据,所以算半个离线数据结构。  

      

    直接上代码

    拿洛谷的平衡树模板为例。

    这里由于懒得写线段树就拿树状数组代替了。  

    如果开心的话手动改成线段树就可以了。  

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int N=1e6+1000;
     4 int read(){
     5     char c;int num,f=1;
     6     while(c=getchar(),!isdigit(c))if(c=='-')f=-1;num=c-'0';
     7     while(c=getchar(), isdigit(c))num=num*10+c-'0';
     8     return f*num;
     9 }
    10 int order[N],act[N][2],cnt,t[N],n;
    11 bool cmp(int a,int b){return a<b;}
    12 int fd(int a){
    13     int l=1,r=cnt,mid;
    14     while(l<=r){
    15         mid=(l+r)>>1;
    16         if(order[mid]==a)return mid;
    17         else if(order[mid]>a)r=mid-1;
    18         else l=mid+1;
    19     }
    20     return -1;
    21 }
    22 void add(int x,int val){for(;x<=cnt;x+=x&-x)t[x]+=val;}
    23 int query(int x){
    24     int ans=0;
    25     for(;x;x-=x&-x)ans+=t[x];
    26     return ans;
    27 }
    28 void Insert(int x){add(x,1);}
    29 void Del(int x){if(query(x)-query(x-1))add(x,-1);}
    30 int Getrank(int x){return query(x-1)+1;}
    31 int Getnum(int rk){
    32     int l=0,r=cnt,mid,a,b;
    33     while(l<=r){
    34         mid=(l+r)>>1;
    35         a=query(mid-1);
    36         b=query(mid);
    37         if(b>=rk&&a<rk)return order[mid];
    38         if(b<rk)l=mid+1;
    39         else r=mid-1;
    40     }
    41     return -1;
    42 }
    43 int Getpre(int x){return Getnum(Getrank(x)-1);}
    44 int Getnxt(int x){return Getnum(query(x)+1);}
    45 
    46 int main()
    47 {
    48     n=read();
    49     for(int i=1;i<=n;i++){
    50         act[i][0]=read();
    51          act[i][1]=read();
    52         order[++cnt]=act[i][1];
    53     }
    54     sort(order+1,order+1+cnt,cmp);
    55     cnt=unique(order+1,order+1+cnt)-order;
    56     for(int i=1;i<=n;i++){
    57         int opt=act[i][0],x=fd(act[i][1]);
    58         if(opt==1)Insert(x);
    59         if(opt==2)Del(x);
    60         if(opt==3)printf("%d
    ",Getrank(x));
    61         if(opt==4)printf("%d
    ",Getnum(act[i][1]));
    62         if(opt==5)printf("%d
    ",Getpre(x));
    63         if(opt==6)printf("%d
    ",Getnxt(x));
    64     }
    65     return 0;
    66 }
    View Code
  • 相关阅读:
    用Java开发第一个APP
    去除字符串空格并竖向排列
    并发容器 concurrentHashMap--1.7 更改
    java并发容器CopyOnWriteArrayList 使用场景和内部实现分析
    java非并发容器ArrayList 和 LinkedList 优缺点比较及其实现源码分析
    并发容器之CopyOnWriteArrayList分析
    单例模式
    [Android]知识总结一:Activity
    阿里巴巴fastjson的使用问题
    java跨域请求的方式
  • 原文地址:https://www.cnblogs.com/onglublog/p/9986492.html
Copyright © 2011-2022 走看看