[模板] 线段树维护桶排序

线段树维护桶排序

类似于【HEOI2016】排序

可以用线段树维护 \(0/1\) 序列,同样也可以维护 \(26\) 个字母或者有限个数字(合理外推的结果)。

代码非原创。

#include<bits/stdc++.h>
#define re register
using namespace std;
char a[100010];
int f[27],n,m;
struct zxb
{int l,r,ji;}tree[400010];
namespace AYX
{   inline void pushup(int x){if(tree[x<<1].ji==tree[x<<1|1].ji)tree[x].ji=tree[x<<1].ji;}  
    inline void pushdown(int x){if(tree[x].ji)tree[x<<1].ji=tree[x<<1|1].ji=tree[x].ji;tree[x].ji=0;}
    inline void build(int x,int l,int r)
    {   if(l==r)
        {   tree[x].ji=a[l]-'a'+1;
            return;
        }
        int mid=(l+r)>>1;
        build(x<<1,l,mid);
        build(x<<1|1,mid+1,r);
        pushup(x);
    }
    inline void query(int x,int l,int r,int L,int R)
    {   if(l>=L and r<=R and tree[x].ji)
        {f[tree[x].ji]+=r-l+1;return;}
        pushdown(x);
        int mid=(l+r)>>1;
        if(mid>=L)query(x<<1,l,mid,L,R);
        if(mid<R)query(x<<1|1,mid+1,r,L,R);
    }
    inline void update(int x,int l,int r,int L,int R,int j)
    {   if(l>=L and r<=R){tree[x].ji=j;return;}
        pushdown(x);
        int mid=(l+r)>>1;
        if(mid<R)update(x<<1|1,mid+1,r,L,R,j);
        if(mid>=L)update(x<<1,l,mid,L,R,j);
    }
    inline void p(int x,int l,int r)
    {   if(tree[x].ji){for(int i=l;i<=r;++i)putchar(tree[x].ji+'a'-1);return;}
        int mid=(l+r)>>1;
        p(x<<1,l,mid);
        p(x<<1|1,mid+1,r);
    }
    inline short main()
    {   //freopen("c.in","r",stdin);    
        scanf("%d%d",&n,&m);
        scanf("%s",a+1);
        build(1,1,n);
        while(m--)
        {   int l,r,opt,sum=0;
            scanf("%d%d%d",&l,&r,&opt);
            memset(f,0,sizeof(f));
            query(1,1,n,l,r);sum=l;
            if(opt==1)
            {   
                for(int i=1;i<=26;++i)
                if(f[i])update(1,1,n,sum,sum+f[i]-1,i),sum+=f[i];
            }
            else
            {   for(int i=26;i;--i)
                if(f[i])update(1,1,n,sum,sum+f[i]-1,i),sum+=f[i];
            }
        }
        p(1,1,n);
    }
}
signed main()
{return AYX::main();}
posted @ 2021-08-12 17:29  ¶凉笙  阅读(44)  评论(0编辑  收藏  举报