8.1.T1

string

题面什么的

抱歉,被我咕咕咕了


考场思路:

  sort大法好

  n2log2n过 40% 令人着实兴奋

正解:

  线段树+桶

  利用只有26个字母的优势

  好吧,26个字母,只怪我没想到

   代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define l(k)	(k<<1)
#define r(k)	(l(k)|1)
const int maxn=1e5+5;
struct tree{
	int l,r,sum;
}t[maxn<<5];
int a[maxn];
int n,m,bj[maxn],b[27];
void upc(int k)
{
	if(t[k].l==t[k].r)
		return;
	t[k].sum=(t[l(k)].sum==t[r(k)].sum?t[l(k)].sum:0);
}
void build(int k,int l,int r)
{
	/*cout<<k<<" "<<l<<" "<<r<<endl;*/
	t[k].l=l,t[k].r=r;
	if(l==r)
	{
		t[k].sum=a[l];
		bj[l]=k;
		return;
	}
	int mid=(l+r)>>1;
	build(l(k),l,mid);
	build(r(k),mid+1,r);
	upc(k);
}
void cl(int k)
{
	if(!t[k].sum)	return;
	if(t[k].l!=t[k].r)	t[l(k)].sum=t[r(k)].sum=t[k].sum;
}
void add(int k,int p,int l,int r)
{
	if((t[k].l>=l&&t[k].r<=r)||t[k].sum==p)
	{
		t[k].sum=p;
		cl(k);
		return;
	}
	cl(k);
	int mid=(t[k].l+t[k].r)>>1;
	if(l<=mid)	add(l(k),p,l,r);
	if(r>mid)	add(r(k),p,l,r);
	upc(k);
}
void cha(int k,int l,int r)
{
	/*cout<<k<<" "<<l<<" "<<r<<endl;*/
	cl(k);
	if(l>t[k].r||r<t[k].l)
		return;
	if(l<=t[k].l&&t[k].r<=r&&t[k].sum)
	{
		b[t[k].sum]+=t[k].r-t[k].l+1;
		return;
	}
	cl(k);
	int mid=(t[k].l+t[k].r)>>1;
	if(l<=mid)	cha(l(k),l,r);
	if(r>mid)	cha(r(k),l,r);
}
void work(int k,int l,int r)
{
	memset(b,0,sizeof(b));
	cha(1,l,r);
	/*for(int q=1;q<=26;q++)
		if(b[q])
			cout<<(char)(q+'a'-1)<<" "<<b[q]<<endl;*/
	int tmp=l;
	if(k)
	{
		for(int q=1;q<=26;q++)
			if(b[q])
				add(1,q,tmp,tmp+b[q]-1),tmp+=b[q];
	}
	else
		for(int q=26;q>=1;q--)
			if(b[q])
				add(1,q,tmp,tmp+b[q]-1),tmp+=b[q];
}
void down(int k)
{
	cl(k);
	if(t[k].l==t[k].r)	return;
	down(l(k)),down(r(k));
}
int main()
{
	cin>>n>>m;
	for(int q=1;q<=n;q++)
	{
		char ch=getchar();
		while(ch<'a'||ch>'z')
			ch=getchar();
		a[q]=ch-'a'+1;
	}
	build(1,1,n);
	for(int q=1,x,y,z;q<=m;q++)
		cin>>x>>y>>z,work(z,x,y);
	down(1);
	for(int q=1;q<=n;q++)
		putchar(t[bj[q]].sum+'a'-1);
	puts("");
}
原文地址:https://www.cnblogs.com/ooovooo/p/11288845.html