string(某道线段树题)

26棵线段树=。=区间修改。如果L,R这段区间升序,那么从a依次放到z,降序,从z放到a.

怎么放呢?

假设放b

把l- r所有b取出。放到a后面。

注意优化

1.如果这段区间某字母的个数为0,就不用去放了

2.查找某区间某字母个数时,如果另一个区间,包含查询区间,但这一区间某字母个数为0,就不用递归了。

#include<bits/stdc++.h>
using namespace std;
int n,m,a[100005],siz[27][450005],tag[27][450005],flag[27][450005]; 
inline void read(int &x)
{
	x = 0;
	int f  = 0;
	char c = getchar();
	while(c < '0' || c > '9')
	{
		if(c == '-') f = 1; 
		c = getchar();
	}
	while(c >= '0' && c <= '9')
	{
		x = 10 * x + c - '0';
		c = getchar();
	}
	if(f) x = -x;
}
void update(int o,int ha)
{
	siz[ha][o] = siz[ha][o*2] + siz[ha][o*2 + 1] ;
}
void build(int o,int l,int r,int ha)
{
	if(l == r)
	{
		if(a[l] == ha) siz[ha][o]++;
		return;
	}
	int mid = (l + r) / 2;
	build(o*2, l, mid, ha);
	build(o*2+1, mid+1, r, ha);
	update(o,ha);
}
void pushdown(int o,int ha,int l,int r)
{
	if(flag[ha][o])
	{
		int mid = (l + r) / 2;
		siz[ha][o * 2] = (mid - l + 1) * tag[ha][o];
		siz[ha][o * 2 + 1] = (r - mid) * tag[ha][o];
		flag[ha][o*2] = flag[ha][o*2+1] = 1;
		flag[ha][o] = 0;
		tag[ha] [o*2]= tag[ha][o*2+1] = tag[ha][o];
		tag[ha][o] = 0;
	}
}
void modify(int o,int l,int r,int ql,int qr,int val,int ha)
{
	if(ql <= l && r <= qr)
	{
		siz[ha][o] = (r - l + 1) * val;
		tag[ha][o] = val;
		flag[ha][o] = 1;
		return;
	}
	pushdown(o,ha,l,r);
	int mid = (l + r) /2;
	if(ql <= mid) modify(o*2, l, mid, ql, qr,val, ha);
	if(qr > mid) modify(o*2+1, mid+1, r, ql, qr,val,ha);
	update(o,ha);
}
int qurey(int o,int l,int r,int ql,int qr,int ha)
{
	if(siz[ha][o] == 0) return 0;
	if(ql <= l && r <= qr)
	{
			tag[ha][o] = 0;
			flag[ha][o] = 1;
		int he = siz[ha][o];
		 siz[ha][o] = 0;
		return he;
	}
	pushdown(o,ha,l,r);
	int rt = 0,mid = (l + r) /2;
	if(ql <= mid) rt += qurey(o*2, l, mid, ql, qr, ha);
	if(qr > mid) rt += qurey(o*2+1, mid+1, r, ql, qr,ha);
	update(o,ha);
	return rt;
}
int qurey1(int o,int l,int r,int pos,int ha)
{
		if(siz[ha][o] == 0) return 0;
	if(l == r)
	{
		return siz[ha][o];
	}
	pushdown(o,ha,l,r);
	int mid = (l + r) / 2;
	if(pos <= mid) return qurey1(o*2, l, mid, pos, ha);
	else return qurey1(o*2+1,mid+1,r,pos,ha);
}
int main()
{
	freopen("string.in","r",stdin);
	freopen("string.out","w",stdout);
	read(n);
	read(m);
	for(register int i = 1; i <= n; i++)
	{
		char s;
		scanf("%c",&s);
		a[i] = s - 'a' + 1;
	}	
	for(register  int i = 1; i <= 26; i++)
	{
	   build(1,1,n,i);
	}
	for(register int k = 1; k <= m; k++)
	{
		int l,r,x;
		read(l); read(r); read(x);
		int las = l;
		if(x == 1)
		for(register int i = 1; i <= 26; i++)
		   {
			int he = qurey(1,1,n,l,r,i);
		if(he > 0)	modify(1,1,n,las,las + he - 1,1,i);
			 las = las + he;
		   }	
		else
		for(register int i = 26; i >= 1; i--)
		{
			int he = qurey(1,1,n,l,r,i);
		if(he > 0) modify(1,1,n,las,las + he - 1,1,i);
			las = las + he;
		}
	}
	for(register int k = 1; k <= n; k++)
	{
		for(register int i = 1; i <= 26; i++)
		{
			int he = qurey1(1,1,n,k,i);
			if(he == 1){
				printf("%c",i-1+'a');
			    break;
			}
		}
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/Bluelanzhan/article/details/83512396