Codeforces558E A Simple Task(线段树)

题目

Source

http://codeforces.com/problemset/problem/558/E

Description

This task is very simple. Given a string S of length n and q queries each query is on the format i j k which means sort the substring consisting of the characters from i to j in non-decreasing order if k = 1 or in non-increasing order if k = 0.

Output the final string after applying the queries.

Input

The first line will contain two integers n, q (1 ≤ n ≤ 105, 0 ≤ q ≤ 50 000), the length of the string and the number of queries respectively.

Next line contains a string S itself. It contains only lowercase English letters.

Next q lines will contain three integers each i, j, k (1 ≤ i ≤ j ≤ n, ).

Output

Output one line, the string S after applying the queries.

Sample Input

10 5
abacdabcda
7 10 0
5 8 1
1 4 0
3 6 0
7 10 1

 

10 1
agjucbvdfk
1 10 1

Sample Output

cbcaaaabdd

abcdfgjkuv

 

分析

题目大概说给一个由26个小写英文字母组成的序列,进行若干次操作,每次将一个区间升序或降序,问序列最后是怎样的。

 

26个线段树搞。。没什么。。

 

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 111111

struct Ret{
	int ret[26];
	void operator+=(const Ret &r){
		for(int i=0; i<26; ++i){
			ret[i]+=r.ret[i];
		}
	}
};
int sum[26][MAXN<<2],tag[26][MAXN<<2];
int N,x,y,z;
Ret query(int i,int j,int k){
	if(x<=i && j<=y){
		Ret r={0};
		for(int t=0; t<26; ++t) r.ret[t]+=sum[t][k];
		return r;
	}
	int mid=i+j>>1;
	for(int t=0; t<26; ++t){
		if(tag[t][k]){
			tag[t][k<<1]=tag[t][k];
			tag[t][k<<1|1]=tag[t][k];
			if(tag[t][k]==1){
				sum[t][k<<1]=mid-i+1;
				sum[t][k<<1|1]=j-mid;
			}else{
				sum[t][k<<1]=0;
				sum[t][k<<1|1]=0;
			}
			tag[t][k]=0;
		}
	}
	Ret r={0};
	if(x<=mid) r+=query(i,mid,k<<1);
	if(y>mid) r+=query(mid+1,j,k<<1|1);
	return r;
}
void update(int i,int j,int k,int flag){
	if(x>y) return;
	if(x<=i && j<=y){
		tag[z][k]=flag;
		if(flag==1) sum[z][k]=j-i+1;
		else sum[z][k]=0;
		return;
	}
	int mid=i+j>>1;
	if(tag[z][k]){
		tag[z][k<<1]=tag[z][k];
		tag[z][k<<1|1]=tag[z][k];
		if(tag[z][k]==1){
			sum[z][k<<1]=mid-i+1;
			sum[z][k<<1|1]=j-mid;
		}else{
			sum[z][k<<1]=0;
			sum[z][k<<1|1]=0;
		}
		tag[z][k]=0;
	}
	if(x<=mid) update(i,mid,k<<1,flag);
	if(y>mid) update(mid+1,j,k<<1|1,flag);
	sum[z][k]=sum[z][k<<1]+sum[z][k<<1|1];
}

char str[MAXN];
int main(){
	int n,m;
	scanf("%d%d%s",&n,&m,str+1);
	for(N=1; N<n; N<<=1);
	for(int i=1; i<=n; ++i){
		x=i; y=i; z=str[i]-'a';
		update(1,N,1,1);
	}
	
	int a;
	while(m--){
		scanf("%d%d%d",&x,&y,&a);
		Ret r=query(1,N,1);
		for(z=0; z<26; ++z){
			update(1,N,1,-1);
		}
		if(a==1){
			int now=x;
			for(z=0; z<26; ++z){
				x=now; y=now+r.ret[z]-1;
				update(1,N,1,1);
				now+=r.ret[z];
			}
		}else{
			int now=x;
			for(z=25; z>=0; --z){
				x=now; y=now+r.ret[z]-1;
				update(1,N,1,1);
				now+=r.ret[z];
			}
		}
	}
	for(int i=1; i<=n; ++i){
		x=i; y=i;
		Ret r=query(1,N,1);
		for(int j=0; j<26; ++j){
			if(r.ret[j]) putchar(j+'a');
		}
	}
	return 0;
}

 

posted @ 2016-09-30 09:27  WABoss  阅读(285)  评论(0编辑  收藏  举报