Codeforces - Letters Removing

题目链接:Codeforces - Letters Removing


每次我们需要从删除之后的序列,找到原来对应的区间。

其实就是一个第k大的问题。平衡树或者权值树维护即可。

然后因为只有删除操作,我们直接从set当中删除即可。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e5+10;
int n,m,sum[N<<2];	char str[N],op[3];
set<int> s[200];
void change(int p,int l,int r,int x,int v){
	if(l==r){sum[p]+=v; return ;}
	int mid=l+r>>1;
	if(x<=mid)	change(p<<1,l,mid,x,v);
	else change(p<<1|1,mid+1,r,x,v);
	sum[p]=sum[p<<1]+sum[p<<1|1];
}
int kth(int p,int l,int r,int k){
	if(l==r)	return l;	int mid=l+r>>1;
	if(sum[p<<1]>=k)	return kth(p<<1,l,mid,k);
	else 	return kth(p<<1|1,mid+1,r,k-sum[p<<1]);
}
void out(int p,int l,int r){
	if(!sum[p])	return ;
	if(l==r){printf("%c",str[l]); return ;}
	int mid=l+r>>1;
	out(p<<1,l,mid),out(p<<1|1,mid+1,r);
}
signed main(){
	cin>>n>>m;	scanf("%s",str+1);
	for(int i=1;i<=n;i++)	s[str[i]].insert(i),change(1,1,n,i,1);
	for(int i=1,l,r;i<=m;i++){
		scanf("%d %d %s",&l,&r,op);
		int ql=kth(1,1,n,l),qr=kth(1,1,n,r);
		auto itl=s[op[0]].lower_bound(ql),itr=s[op[0]].upper_bound(qr);
		for(auto j=itl;j!=itr;j++)	change(1,1,n,*j,-1);
		s[op[0]].erase(itl,itr);
	}
	out(1,1,n);
	return 0;
}
发布了809 篇原创文章 · 获赞 246 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/105219023
今日推荐