码迷,mamicode.com
首页 > 其他好文 > 详细

CF558E A Simple Task

时间:2019-08-29 11:22:57      阅读:91      评论:0      收藏:0      [点我收藏+]

标签:cal   桶排序   +=   思想   不可   print   线段   play   sum   

CF558E A Simple Task    

WOC怎么又一个simple task?     

操作就是区间排序+最终询问     

第一反应是Splay(不对呀,我明明不会Splay的......??)    

后来看了看,感觉Splay不可做(我连Splay都不会,怎么就觉得不能做了)    

感觉线段树比较靠谱     

观察题目发现小写字母只有26个(常识)     

往元素上去做文章     

将排序用另外一种方式呈现      

用桶排序的思想    

开一个桶记录区间1~26字母出现的个数    

然后区间赋值,达到排序目的    

输出只要遍历一下线段树的叶子节点即可    

代码:    

#include<bits/stdc++.h>
using namespace std;
const int N=100005;
int n,m;
int a[N];
int cal[30];
struct Sugment_Tree{
    int LZT[N<<2];
    int t[N<<2][30];
    #define il inline
    #define mid (l+r)/2
    Sugment_Tree(){memset(t,0,sizeof(t));memset(LZT,0,sizeof(LZT));}
    il void push_up(int num){
        for(int i=1;i<=26;i++){t[num][i]=t[num<<1][i]+t[num<<1|1][i];}
    }
    il void push_down(int l,int r,int num){
        if(!LZT[num]) return;
        LZT[num<<1]=LZT[num];
        LZT[num<<1|1]=LZT[num];
        memset(t[num<<1],0,sizeof(t[num<<1]));
        memset(t[num<<1|1],0,sizeof(t[num<<1|1]));
        t[num<<1][LZT[num]]=(mid-l+1);
        t[num<<1|1][LZT[num]]=(r-(mid+1)+1);
        LZT[num]=0;
    }
    il void build(int l,int r,int num){
        if(l==r){
            t[num][a[l]]=1;
            return;
        }
        build(l,mid,num<<1);
        build(mid+1,r,num<<1|1);
        push_up(num);
    }
    il void upt(int l,int r,int num,int L,int R,int SUM){
        if(l>R||r<L) return;
        if(l>=L&&r<=R){
            LZT[num]=SUM;
            memset(t[num],0,sizeof(t[num]));
            t[num][SUM]=r-l+1;
            return;
        }
        push_down(l,r,num);
        upt(l,mid,num<<1,L,R,SUM);
        upt(mid+1,r,num<<1|1,L,R,SUM);
        push_up(num);
    }
    il int ask(int l,int r,int num,int L,int R,int SUM){
        if(l>R||r<L) return 0;
        if(l>=L&&r<=R){
            return t[num][SUM];
        }
        push_down(l,r,num);
        return ask(l,mid,num<<1,L,R,SUM)+ask(mid+1,r,num<<1|1,L,R,SUM);
    }
    il void output(int l,int r,int num){
        if(l==r){
            for(int i=1;i<=26;i++){
                if(t[num][i]) printf("%c",a+i-1);
            }
            return;
        }
        push_down(l,r,num); 
        output(l,mid,num<<1);
        output(mid+1,r,num<<1|1);
    }
}T;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        char c;
        cin>>c;
        a[i]=c-a+1;
    }
    T.build(1,n,1);
    //T.output(1,n,1);
    while(m--){
        int l,r,x;
        scanf("%d%d%d",&l,&r,&x);
        memset(cal,0,sizeof(cal));
        for(int i=1;i<=26;i++){
            cal[i]=T.ask(1,n,1,l,r,i);
        }
        int L=l;
        if(x==1){
            for(int i=1;i<=26;i++){
                T.upt(1,n,1,L,L+cal[i]-1,i);
                L+=cal[i];
            }
        } 
        else{
            for(int i=26;i>=1;i--){
                T.upt(1,n,1,L,L+cal[i]-1,i);
                L+=cal[i];
            }
        } 
    }
    T.output(1,n,1);
    return 0;
} 

 

CF558E A Simple Task

标签:cal   桶排序   +=   思想   不可   print   线段   play   sum   

原文地址:https://www.cnblogs.com/QYJ060604/p/11428382.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!