Codeforces 558E A Simple Task
Posted NINGLONG
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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; }
以上是关于Codeforces 558E A Simple Task的主要内容,如果未能解决你的问题,请参考以下文章
codeforces 558E A Simple Task 线段树