codeforces 558E. A Simple Task

版权声明:蒟蒻Blog随意转载 https://blog.csdn.net/a1799342217/article/details/82859889

线段树

题目传送门

题目大意: 给你一个字符串,每次对一个区间进行降序或升序排序,求最后的字符串。

开26棵线段树,每一棵维护一个字母的位置,直接模拟就好了。 O ( 26 q log n ) O(26q\log n) 稳得很。

还有一种做法是基于这道题的。每做一次就可以知道其他位置的相对大小关系,这样做26次就全都知道了。复杂度是一样的,不过要离线。

我想的时候自己把正解毙了。。。

代码:

#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100005
#define F inline
using namespace std;
struct tree{ int l,r,x,f; }t[27][N<<2];
int n,m,mx,a[N],s[27];
F char readc(){
	static char buf[100000],*l=buf,*r=buf;
	if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
	return l==r?EOF:*l++;
}
F int _read(){
	int x=0; char ch=readc();
	while (!isdigit(ch)&&!islower(ch)) ch=readc();
	if (islower(ch)) return ch;
	while (isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=readc();
	return x;
}
F void pshp(int id,int x){ t[id][x].x=t[id][x<<1].x+t[id][x<<1|1].x; }
F void pshd(int id,int x){
	if (t[id][x].f==-1) return; int l=x<<1,r=x<<1|1;
	t[id][l].x=(t[id][l].r-t[id][l].l+1)*t[id][x].f;
	t[id][r].x=(t[id][r].r-t[id][r].l+1)*t[id][x].f;
	t[id][l].f=t[id][r].f=t[id][x].f,t[id][x].f=-1;
}
void build(int id,int x,int l,int r){
	t[id][x]=(tree){l,r,0,-1}; int mid=l+r>>1;
	if (l==r) return void(t[id][x].x=id==a[l]);
	build(id,x<<1,l,mid),build(id,x<<1|1,mid+1,r),pshp(id,x);
}
void mdfy(int id,int x,int l,int r,int w){
	if (l>r||t[id][x].l>r||t[id][x].r<l) return;
	if (t[id][x].l>=l&&t[id][x].r<=r)
		return void(t[id][x].x=(t[id][x].f=w)*(t[id][x].r-t[id][x].l+1));
	pshd(id,x),mdfy(id,x<<1,l,r,w),mdfy(id,x<<1|1,l,r,w),pshp(id,x);
}
int srch(int id,int x,int l,int r){
	if (t[id][x].l>r||t[id][x].r<l) return 0;
	if (t[id][x].l>=l&&t[id][x].r<=r) return t[id][x].x;
	return pshd(id,x),srch(id,x<<1,l,r)+srch(id,x<<1|1,l,r);
}
int main(){
	n=_read(),m=_read();
	for (int i=1;i<=n;i++) mx=max(mx,a[i]=_read()-'a'+1);
	for (int i=1;i<=mx;i++) build(i,1,1,n);
	while (m--){
		int l=_read(),r=_read(),f=_read();
		for (int i=1;i<=mx;i++)
			s[i]=srch(i,1,l,r),mdfy(i,1,l,r,0);
		if (!f)
			for (int i=mx;i;i--)
				s[i]+=s[i+1],mdfy(i,1,l+s[i+1],l+s[i]-1,1);
		else
			for (int i=1;i<=mx;i++)
				s[i]+=s[i-1],mdfy(i,1,l+s[i-1],l+s[i]-1,1);
	}
	for (int i=1;i<=n;i++)
		for (int j=1;j<=mx;j++)
			if (srch(j,1,i,i)){ putchar(j+'a'-1); break; }
	return 0;
}

猜你喜欢

转载自blog.csdn.net/a1799342217/article/details/82859889