zoukankan      html  css  js  c++  java
  • 可持久化线段树(主席树)

    主席树留坑

    可持久化权值线段树:

    区间第k小数

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<cmath>
    #include<map>
    #include<bitset>
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define dwn(i,a,b) for(int i=(a);i>=(b);--i)
    using namespace std;
    typedef long long ll;
    const int N=200000;
    int n,m,cnt,tot=0;
    int a[N+10],b[N+10],rt[N+10];
    int sum[100*N+10],tl[100*N+10],tr[100*N+10];
    int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-') f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=(x<<3)+(x<<1)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    int build(int l,int r)
    {
        int t=++tot;
        sum[tot]=0;
        if(l<r)
        {
            int mid=(l+r)>>1;
            tl[t]=build(l,mid);
            tr[t]=build(mid+1,r);
        }
        return t;
    }
    int update(int pre,int l,int r,int x)
    {
        int t=++tot;
        tl[t]=tl[pre];tr[t]=tr[pre];sum[t]=sum[pre]+1;
        if(l<r)
        {
            int mid=(l+r)>>1;
            if(x<=mid) tl[t]=update(tl[pre],l,mid,x);
            else tr[t]=update(tr[pre],mid+1,r,x);
        }
        return t;
    }
    int ask_sum(int u,int v,int l,int r,int k)
    {
        if(l>=r) return l;
        int x=sum[tl[v]]-sum[tl[u]];
        int mid=(l+r)>>1;
        if(k<=x) return ask_sum(tl[u],tl[v],l,mid,k);
        else return ask_sum(tr[u],tr[v],mid+1,r,k-x);
    }
    int main()
    {
        n=read(),m=read();
        rep(i,1,n)
        {
            a[i]=b[i]=read();
        }
        sort(b+1,b+n+1);
        cnt=unique(b+1,b+n+1)-b-1;
        rt[0]=build(1,cnt);
        rep(i,1,n)
        {
            int t=lower_bound(b+1,b+cnt+1,a[i])-b;
            rt[i]=update(rt[i-1],1,cnt,t);
        }
        rep(i,1,m)
        {
            int l=read(),r=read(),k=read();
            printf("%d
    ",b[ask_sum(rt[l-1],rt[r],1,cnt,k)]);
        }
        return 0;
    }
    

    可持久化数组-线段树实现:

    可持久化数组

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<cmath>
    #include<map>
    #include<bitset>
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define dwn(i,a,b) for(int i=(a);i>=(b);--i)
    using namespace std;
    typedef long long ll;
    const int N=1000000;
    int n,m,a[N+10],rt[N+10],val[40*N+10],tl[40*N+10],tr[40*N+10],cnt=0,tot=0;
    int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-') f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=(x<<3)+(x<<1)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    int build(int l,int r)
    {
        int t=++tot;
        if(l==r)
        {
            val[t]=a[l];
            return t;
        }
        int mid=(l+r)>>1;
        tl[t]=build(l,mid);
        tr[t]=build(mid+1,r);
        return t;
    }
    int update(int pre,int l,int r,int x,int d)
    {
        int t=++tot;
        if(l==r)
        {
            val[t]=d;
            return t;
        }
        tl[t]=tl[pre],tr[t]=tr[pre];
        int mid=(l+r)>>1;
        if(x<=mid) tl[t]=update(tl[pre],l,mid,x,d);
        else tr[t]=update(tr[pre],mid+1,r,x,d);
        return t;
    }
    int ask_val(int t,int l,int r,int x)
    {
        if(l==r) return val[t];
        int mid=(l+r)>>1;
        if(x<=mid) return ask_val(tl[t],l,mid,x);
        else return ask_val(tr[t],mid+1,r,x);
    }
    int main()
    {
        n=read(),m=read();
        rep(i,1,n) a[i]=read();
        rt[0]=build(1,n);
        rep(i,1,m)
        {
            int t=read(),opt=read(),x=read();
            if(opt==1) {int d=read();rt[++cnt]=update(rt[t],1,n,x,d);}
            if(opt==2) {printf("%d
    ",ask_val(rt[t],1,n,x));rt[++cnt]=rt[t];}
        }
        return 0;
    }
    
  • 相关阅读:
    RSS简易阅读器vb.net源代码
    [建议]有关图片地址的建议
    [音乐欣赏]wind flowers
    有个叫计算机的比我笨
    一个朋友画的建筑设计手绘图与其想到的
    [推荐]华建小翻--QQ里的一个不错的服务商
    爆强的广告
    [学习日记]重构简易RSSREADER的UML类图
    [音乐欣赏]红颜
    [音乐欣赏]花与琴的流星
  • 原文地址:https://www.cnblogs.com/MYsBlogs/p/11379844.html
Copyright © 2011-2022 走看看