Codeforces 558E A Simple Task

题意:给定一个字符串,以及m次操作,每次操作对字符串的一个子区间进行升序或降序排序,求m次操作后的串

考虑桶排,发现线段树可以模拟桶排的过程,所以对26个字母分别建立线段树即可

#include<bits/stdc++.h>
using namespace std;
#define MAXN 1000000+10
struct tree{int sum,tag;}tr[MAXN*4][27];
char s[MAXN];
int n,m,cnt[27];
void pushup(int k,int x){tr[k][x].sum=tr[k<<1][x].sum+tr[k<<1|1][x].sum;}
void pushdown(int k,int x,int l,int r){
    int mid=(l+r)>>1;
    if(tr[k][x].tag==1){
        tr[k<<1][x].sum=(mid-l+1);tr[k<<1|1][x].sum=(r-mid);
        tr[k<<1][x].tag=tr[k<<1|1][x].tag=1;
        tr[k][x].tag=0;
    }
    else if(tr[k][x].tag==2){
        tr[k<<1][x].sum=tr[k<<1|1][x].sum=0;
        tr[k<<1][x].tag=tr[k<<1|1][x].tag=2;
        tr[k][x].tag=0;
    }
}
void build(int k,int l,int r,int x){
    tr[k][x].tag=0;
    if(l==r){
        tr[k][x].sum=0;
        return;
    }
    int mid=(l+r)>>1;
    build(k<<1,l,mid,x);
    build(k<<1|1,mid+1,r,x);
    pushup(k,x);
}
void update(int k,int l,int r,int L,int R,int val,int x){
    if(l>=L&&r<=R){
        if(val==1)tr[k][x].sum=r-l+1;
        else tr[k][x].sum=0;
        tr[k][x].tag=val;
        return;
    }
    pushdown(k,x,l,r);
    int mid=(l+r)>>1;
    if(R<=mid)update(k<<1,l,mid,L,R,val,x);
    else if(L>mid)update(k<<1|1,mid+1,r,L,R,val,x);
    else update(k<<1,l,mid,L,R,val,x),update(k<<1|1,mid+1,r,L,R,val,x);
    pushup(k,x);
}
int query(int k,int l,int r,int L,int R,int x){
    if(l>=L&&r<=R)return tr[k][x].sum;
    pushdown(k,x,l,r);
    int mid=(l+r)>>1;
    if(R<=mid)return query(k<<1,l,mid,L,R,x);
    else if(L>mid)return query(k<<1|1,mid+1,r,L,R,x);
    else return query(k<<1,l,mid,L,R,x)+query(k<<1|1,mid+1,r,L,R,x);
    pushup(k,x);
}
int main(){
    scanf("%d%d",&n,&m);
    scanf("%s",s+1);
    for(int i=0;i<25;i++)build(1,1,n,i);
    for(int i=1;i<=n;i++)update(1,1,n,i,i,1,s[i]-'a');
    while(m--){
        memset(cnt,0,sizeof(cnt));
        int l,r,x;
        scanf("%d%d%d",&l,&r,&x);
        for(int i=0;i<26;i++){
            cnt[i]=query(1,1,n,l,r,i);
            update(1,1,n,l,r,2,i);
        }
        if(x){
            int p=l;
            for(int i=0;i<26;i++){
                if(cnt[i])update(1,1,n,p,p+cnt[i]-1,1,i);    
                p+=cnt[i];
            }
        }
        else{
            int p=l;
            for(int i=25;i>=0;i--){
                if(cnt[i])update(1,1,n,p,p+cnt[i]-1,1,i);
                p+=cnt[i];
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int k=0;k<26;k++)
            if(query(1,1,n,i,i,k)){
                putchar((char)k+'a');
                break;
            }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/NINGLONG/p/7623631.html