Codeforces - A Simple Task

题目链接:Codeforces - A Simple Task


我们可以注意到是字母排序。字母排序和0/1排序是很像的,种类数很少。

所以我们可以开26颗线段树,分别维护某个字母的区间个数。

然后根据要求,从小到大,或者从大到小for循环即可。

最开始l写成r了,一直TLE,所以加了个快读。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10;
int sum[27][N<<2],lazy[27][N<<2],n,m;	char str[N];
inline int read(){
	register int x=0,f=1;register char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
	while (c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return x*f;
}
inline void push_up(int p,int k){
	sum[k][p]=sum[k][p<<1]+sum[k][p<<1|1];
}
inline void push_down(int p,int l,int r,int i){
	if(lazy[i][p]==-1)	return;	int mid=l+r>>1;
	lazy[i][p<<1]=lazy[i][p<<1|1]=lazy[i][p];
	sum[i][p<<1]=(mid-l+1)*lazy[i][p];
	sum[i][p<<1|1]=(r-mid)*lazy[i][p];
	lazy[i][p]=-1;
}
void build(int p,int l,int r){
	if(l==r){sum[str[l]-'a'][p]=1;	return;}
	int mid=l+r>>1;
	build(p<<1,l,mid),build(p<<1|1,mid+1,r);
	for(int i=0;i<26;i++)	push_up(p,i);
}
void change(int p,int l,int r,int ql,int qr,int k,int v){
	if(l==ql&&r==qr){
		lazy[k][p]=v;	sum[k][p]=(r-l+1)*v;	return ;
	}
	int mid=l+r>>1;	push_down(p,l,r,k);
	if(qr<=mid)	change(p<<1,l,mid,ql,qr,k,v);
	else if(ql>mid)	change(p<<1|1,mid+1,r,ql,qr,k,v);
	else	change(p<<1,l,mid,ql,mid,k,v),change(p<<1|1,mid+1,r,mid+1,qr,k,v);
	push_up(p,k);
}
int ask(int p,int l,int r,int ql,int qr,int k){
	if(l==ql&&r==qr)	return sum[k][p];
	int mid=l+r>>1;	push_down(p,l,r,k);
	if(qr<=mid)	return ask(p<<1,l,mid,ql,qr,k);
	else if(ql>mid)	return ask(p<<1|1,mid+1,r,ql,qr,k);
	else	return ask(p<<1,l,mid,ql,mid,k)+ask(p<<1|1,mid+1,r,mid+1,qr,k);
}
void dfs(int p,int l,int r){
	if(l==r){
		for(int i=0;i<26;i++)	if(sum[i][p]){
			str[l]='a'+i;	break;
		}
		return ;
	}
	int mid=l+r>>1;
	for(int i=0;i<26;i++)	push_down(p,l,r,i);
	dfs(p<<1,l,mid),dfs(p<<1|1,mid+1,r);
}
signed main(){
	cin>>n>>m;	scanf("%s",str+1);	build(1,1,n);
	for(int i=0;i<26;i++)	memset(lazy[i],-1,sizeof lazy[i]);
	for(int i=1,l,r,k,num;i<=m;i++){
		l=read(),r=read(),k=read(); num=l-1;
		if(k==1){
			for(int j=0;j<26;j++){
				int s=ask(1,1,n,l,r,j);
				if(!s)	continue;	change(1,1,n,l,r,j,0);
				change(1,1,n,num+1,num+s,j,1);	num+=s;
			}
		}else{
			for(int j=25;j>=0;j--){
				int s=ask(1,1,n,l,r,j);
				if(!s)	continue;	change(1,1,n,l,r,j,0);
				change(1,1,n,num+1,num+s,j,1);	num+=s;
			}
		}
	}
	dfs(1,1,n);
	printf("%s",str+1);
	return 0;
}
发布了553 篇原创文章 · 获赞 242 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/104251588