Codeforces 558E A Simple Task

Discription

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.

Example

Input

10 5abacdabcda7 10 05 8 11 4 03 6 07 10 1

Output

cbcaaaabdd

Input

10 1agjucbvdfk1 10 1

Output

abcdfgjkuv

Note

First sample test explanation:

大概是第一次坐到沙发hhh

可以发现只有26个小写英文,那么就不难了,就是一个常数*26的带标记线段树。。。

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define ll long long
#define maxn 100005
using namespace std;
struct node{
	int sum[28];
	int tag;

	node operator +(const node& u)const{
		node r; r.tag=0;
		for(int i=1;i<27;i++) r.sum[i]=sum[i]+u.sum[i];
		return r;
	}
}a[maxn<<2|1];
int le,ri,opt,w;
int n,m,v,num[30];
char s[maxn];

void build(int o,int l,int r){
	if(l==r){
		a[o].sum[s[l]-‘a‘+1]++;
		return;
	}

	int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1;
	build(lc,l,mid),build(rc,mid+1,r);
	a[o]=a[lc]+a[rc];
}

inline void tol(int o,int tmp,int len){
	memset(a[o].sum,0,sizeof(a[o].sum));
	a[o].sum[tmp]=len;
	a[o].tag=tmp;
}

inline void pushdown(int o,int l,int r){
	if(a[o].tag){
		int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1;
		tol(lc,a[o].tag,mid-l+1);
		tol(rc,a[o].tag,r-mid);
		a[o].tag=0;
	}
}

void update(int o,int l,int r){
	if(l>=le&&r<=ri){
		tol(o,v,r-l+1);
		return;
	}
	pushdown(o,l,r);
	int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1;
	if(le<=mid) update(lc,l,mid);
	if(ri>mid) update(rc,mid+1,r);
	a[o]=a[lc]+a[rc];
}

int query(int o,int l,int r){
	if(l>=le&&r<=ri) return a[o].sum[v];
	pushdown(o,l,r);
	int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1,an=0;
	if(le<=mid) an+=query(lc,l,mid);
	if(ri>mid) an+=query(rc,mid+1,r);
	return an;
}

void print(int o,int l,int r){
	if(l==r){
		for(int i=1;i<27;i++) if(a[o].sum[i]){
			putchar(i-1+‘a‘);
			break;
		}
		return;
	}
	pushdown(o,l,r);
	int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1;
	print(lc,l,mid);
	print(rc,mid+1,r);
}

int main(){
	scanf("%d%d",&n,&m);
	scanf("%s",s+1);
	build(1,1,n);
	while(m--){
		scanf("%d%d%d",&le,&ri,&opt);
		memset(num,0,sizeof(num));
		for(v=1;v<=26;v++) num[v]=query(1,1,n);
		if(opt){
			int pre=le,nxt;
			for(int i=1;i<=26;i++) if(num[i]){
				nxt=pre+num[i]-1,v=i;
				le=pre,ri=nxt;
				update(1,1,n);
				pre=nxt+1;
			}
		}
		else{
			int pre=le,nxt;
			for(int i=26;i;i--) if(num[i]){
				nxt=pre+num[i]-1,v=i;
				le=pre,ri=nxt;
				update(1,1,n);
				pre=nxt+1;
			}
		}
//		print(1,1,n);
	}

	print(1,1,n);
	return 0;
}

  

原文地址:https://www.cnblogs.com/JYYHH/p/8407093.html

时间: 2024-10-05 12:48:11

Codeforces 558E A Simple Task的相关文章

计数排序 + 线段树优化 --- Codeforces 558E : A Simple Task

E. A Simple Task Problem's Link: http://codeforces.com/problemset/problem/558/E Mean: 给定一个字符串,有q次操作,每次操作将(l,r)内的字符升序或降序排列,输出q次操作后的字符串. analyse: 基本思想是计数排序. 所谓计数排序,是对一个元素分布较集中的数字集群进行排序的算法,时间复杂度为O(n),但使用条件很苛刻.首先对n个数扫一遍,映射出每个数字出现的次数,然后再O(n)扫一遍处理出:对于数字ai,

Codeforces 558E A Simple Task (计数排序&amp;&amp;线段树优化)

题目链接:http://codeforces.com/contest/558/problem/E E. A Simple Task time limit per test5 seconds memory limit per test512 megabytes inputstandard input outputstandard output This task is very simple. Given a string S of length n and q queries each quer

codeforces 558E A Simple Task 线段树

题目链接 题意较为简单. 思路: 由于仅仅有26个字母,所以用26棵线段树维护就好了,比較easy. #include <iostream> #include <string> #include <vector> #include <cstring> #include <cstdio> #include <map> #include <queue> #include <algorithm> #include &

[线段树] codeforces 558E. A Simple Task

题意: 给一个长度n的字符串,q次操作,每次操作把[l,r]排序,k=0非递增,k=1非递减. 题解: 采用计数排序的复杂度是O(n?q),无法通过,但有所启示. 可以看出计数就是区间求和,排序就是区间更新,可以用线段树维护. 做法是建立26棵线段树,第i棵树维护第i个字母的位置信息. 计数时,在26棵线段树内分别做一次查询,排序时根据递增还是递减,把相应的区间赋值为相应的字母. #include<bits/stdc++.h> #define lson rt<<1,l,mid #d

CodeForces 11D A Simple Task

题目:http://codeforces.com/problemset/problem/11/D 题意:给定一个图,求图中环的数目 为了消除重复计算,我们要从每个点出发,并将这个点作为环的最小点,再次回到出发点时就变成了环 但是这样依然有重复,会有1条边重复走2次的环,同时还会将大于3的环正向跑一遍逆向跑一遍 所以最后答案需要-m再除2 #include<iostream> #include<cstdio> #include<cstring> #include<s

[CodeForces 11D] A Simple Task - 状态压缩入门

状态压缩/Bitmask 在动态规划问题中,我们会遇到需要记录一个节点是否被占用/是否到达过的情况.而对于一个节点数有多个甚至十几个的问题,开一个巨型的[0/1]数组显然不现实.于是就引入了状态压缩,用一个整数的不同二进制位来表示该节点的状态. Description Given a simple graph, output the number of simple cycles in it. A simple cycle is a cycle with no repeated vertices

Codeforces 11D - A Simple Task (状压DP)

题意 求出一个n个点m个边的图,求简单环有多少(没有重复点和边). 思路 这是个不错的题,这个状压dp保存的状态不是直接的环,而是路径的个数.s表示的状态为一条路径,则dp[s][i]表示以s的最小编号为起点,以i为终点的环的个数.那么我们就可以通过枚举状态,枚举状态中的起点和枚举路径外的终点,然后判断终点和起点是否相连来判断是否成环. 代码 #include <stdio.h> #include <string.h> #include <iostream> #incl

HUST 1341 A - A Simple Task(哈理工 亚洲区选拔赛练习赛)

A - A Simple Task Time Limit:1000MS    Memory Limit:131072KB    64bit IO Format:%lld & %llu SubmitStatusPracticeHUST 1341 Description As is known to all, lots of birds are living in HUST. A bird has s units of food on the first day, and eats k units

A Simple Task

A Simple Task 就像这道题的题目一样,真的是一个简单的题目,题意就是一句话:给一个数N求符合公式N = O * 2P的 O 和 P. 下面我们就一起看一下题吧. Description Given a positive integer n and the odd integer o and the nonnegative integer p such that n = o2^p. Example For n = 24, o = 3 and p = 3. Task Write a pr