zoukankan      html  css  js  c++  java
  • 【模板】可持久化权值线段树(主席树)

    洛谷3834

    主席树入门题,静态区间第k小

    权值线段树:一棵线段树的叶子tree[L=R]节点记录序列中满足a[i]=L=R的数的个数,非叶子节点记录儿子的sum之和;  这样我们就可以快速地求出整个序列的第K小(或第K大)

    为了能够查询区间的第K小,我们在序列1~n的每个位置i建立一棵权值线段树,那么对于区间[X,Y],tree[Y][l=r=k].sum-tree[X-1][l=r=k].sum即为这个区间中满足a[i]=k的数的个数。

    这用到了前缀和的思想。通过这种方式我们可以快速查询区间第k小。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define ls(x) (a[x].l)
     4 #define rs(x) (a[x].r)
     5 #define mid ((l+r)>>1)
     6 using namespace std;
     7 const int maxn=200010;
     8 int n,m,N,x,y,z,tot,b[maxn],c[maxn],root[maxn];
     9 struct tree{int l,r,sum;}a[5000000];
    10 void read(int &k){
    11     k=0; int f=1; char c=getchar();
    12     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    13     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
    14     k*=f;
    15 }
    16 void add(int &u,int l,int r,int pos){
    17     a[++tot]=a[u]; a[u=tot].sum++;
    18     if(l<r) if(pos<=mid) add(ls(u),l,mid,pos); else add(rs(u),mid+1,r,pos);
    19 }
    20 int query(int x,int y,int l,int r,int k){
    21     if(l==r) return l;
    22     if(a[ls(y)].sum-a[ls(x)].sum>=k) return query(ls(x),ls(y),l,mid,k);
    23     else return query(rs(x),rs(y),mid+1,r,k-a[ls(y)].sum+a[ls(x)].sum);
    24 }
    25 int main(){
    26     read(n); read(m);
    27     for(int i=1;i<=n;i++) read(b[i]),c[i]=b[i];
    28     sort(c+1,c+1+n); N=unique(c+1,c+n+1)-c-1;
    29     for(int i=1;i<=n;i++) b[i]=lower_bound(c+1,c+N+1,b[i])-c;
    30     for(int i=1;i<=n;i++) add(root[i]=root[i-1],1,N,b[i]);
    31     while(m--){
    32         read(x); read(y); read(z);
    33         printf("%d
    ",c[query(root[x-1],root[y],1,N,z)]);
    34     }
    35     return 0;
    36 }
    View Code
  • 相关阅读:
    Pytest框架之命令行参数2
    Pytest框架之命令行参数1
    [编程题] 二维数组中的查找
    [编程题]二叉树镜像
    补充基础:栈与队列模型
    6641. 【GDOI20205.20模拟】Sequence
    瞎讲:任意模数MTT
    瞎讲:FFT三次变二次优化
    小米oj 重拍数组求最大和
    小米oj 有多少个公差为2的等差数列
  • 原文地址:https://www.cnblogs.com/DriverLao/p/8024814.html
Copyright © 2011-2022 走看看