F. Letters Removing
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Petya has a string of length n consisting of small and large English letters and digits.

He performs m operations. Each operation is described with two integers l and r and a character c: Petya removes from the string all characters c on positions between l and r, inclusive. It's obvious that the length of the string remains the same or decreases after each operation.

Find how the string will look like after Petya performs all m operations.

Input

The first string contains two integers n and m (1 ≤ n, m ≤ 2·105) — the length of the string and the number of operations.

The second line contains the string of length n, consisting of small and large English letters and digits. Positions in the string are enumerated from 1.

Each of the next m lines contains two integers l and r (1 ≤ l ≤ r), followed by a character c, which is a small or large English letter or a digit. This line describes one operation. It is guaranteed that r doesn't exceed the length of the string s before current operation.

Output

Print the string Petya will obtain after performing all m operations. If the strings becomes empty after all operations, print an empty line.

Examples
input
4 2
abac
1 3 a
2 2 c
output
b
input
3 2
A0z
1 3 0
1 1 z
output
Az
input
10 4
agtFrgF4aF
2 5 g
4 9 F
1 5 4
1 7 a
output
tFrg4
input
9 5
aAAaBBccD
1 4 a
5 6 c
2 3 B
4 4 D
2 3 A
output
AB
Note

In the first example during the first operation both letters 'a' are removed, so the string becomes "bc". During the second operation the letter 'c' (on the second position) is removed, and the string becomes "b".

In the second example during the first operation Petya removes '0' from the second position. After that the string becomes "Az". During the second operations the string doesn't change.

大意:给出一个有数字和字符组成的字符串,M个操作,每次操作给定[L,R]区间,要求删除其中所有的某种字符。

题解:

看到这道题我想用      树状数组+链表解决,但是由于链表顺序查找太慢,会被极端数据卡掉,可以用siz(字符集大小)个set代替(明明就是楼主脑洞错了嘛)。

下面开始正经的正解

正解: 树状数组+平衡树(set)

用平衡树可以轻而易举的找到对应区间的字符(upper_bound 或 lower_bound)。

但是由于删除,区间是在移动的,如何维护?

树状数组即可,起始前 i 个的累加和是 i ,如果删除 j 就把 j 位置上的 1 减去。

那么前 i 个的累加和就是第 i 个字符现在的位置。但是我们的需要是找到现在第 i 个字符原来的位置 ,这个操作树状数组也可以做而且是log级的。

详见代码。

那么问题就圆满解决了,对了,最后别忘了吧set里面剩下的所有字符都拿出来排序输出。

 /*
Welcome Hacking
Wish You High Rating
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<set>
using namespace std;
int read(){
int xx=,ff=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')ff=-;ch=getchar();}
while(ch>=''&&ch<=''){xx=(xx<<)+(xx<<)+ch-'';ch=getchar();}
return xx*ff;
}
set<int>s[];
set<int>::iterator it,iter;
const int maxn=;
int N,M,temp;
struct BIT{
int b[maxn];
void clear()
{memset(b,,sizeof(b));}
inline int lowbit(int x)
{return x&(-x);}
void upd(int x,int p){
while(x<=N){
b[x]+=p;
x+=lowbit(x);
}
}
int query(int x){
int re=;
while(x){
re+=b[x];
x-=lowbit(x);
}
return re;
}
int lower_bound(int v){
int x=,sum=;
for(int i=(<<);i;i>>=)
if(i+x<=N&&sum+b[i+x]<v)
sum+=b[x+=i];
return x+;
}
}bit;
struct my{
int p;
char c;
bool friend operator<(const my&A,const my&B)
{return A.p<B.p;}
}m[maxn];
int cnt=;
int main(){
//freopen("in.txt","r",stdin);
N=read(),M=read();
char ch;int t1,t2;
for(int i=;i<=N;i++){
ch=getchar();
s[ch].insert(i);
bit.upd(i,);
}
while(M--){
t1=read(),t2=read();ch=getchar();
t1=bit.lower_bound(t1),t2=bit.lower_bound(t2);
it=s[ch].lower_bound(t1);
while(it!=s[ch].end()&&(*it)<=t2){
bit.upd(*it,-);
s[ch].erase(it++);
}
}
for(char i='';i<='';i++)
for(it=s[i].begin();it!=s[i].end();it++)
m[++cnt].c=i,m[cnt].p=*it;
for(char i='a';i<='z';i++)
for(it=s[i].begin();it!=s[i].end();it++)
m[++cnt].c=i,m[cnt].p=*it;
for(char i='A';i<='Z';i++)
for(it=s[i].begin();it!=s[i].end();it++)
m[++cnt].c=i,m[cnt].p=*it;
sort(m+,m++cnt);
for(int i=;i<=cnt;i++)
printf("%c",m[i].c);
return ;
}

最新文章

  1. shell简单用法笔记(shell中数值运算)二
  2. 0030 Java学习笔记-面向对象-垃圾回收、(强、软、弱、虚)引用
  3. html5 请求的URL转成 OC可用属性字符串显示
  4. iOS CFNetwork报错
  5. makefile编写要点
  6. [转载]UML用例图总结
  7. 因GIT默认忽略.dll文件导致的Visual Studio项目通过Bamboo编译失败
  8. ORACLE 查看有多个执行计划的SQL语句
  9. Erlang数据类型的表示和实现(5)——binary
  10. Collection的toArray()使用上需要注意的地方
  11. ANTLR3完全参考指南读书笔记[02]
  12. is not in the sudoers file 解决(转)
  13. linux 小技巧总结
  14. C++ primer 中文第三版 阅读笔记 第八章
  15. Java线程池使用
  16. OpenCV——彩色图像转成灰度图像
  17. D3.js force力导向图用指定的字段确定link的source和target,默认是索引
  18. (转)Python中的模块循环导入问题
  19. 【笔记】《深入浅出MFC》第6章 MFC程序的生死因果
  20. uboot-2012.04.01移植编译前准备

热门文章

  1. JS——筋斗云案例
  2. Centos安装smokeping教程
  3. Dispatch Queues 线程池
  4. Resetting the SMC &amp; PRAM
  5. Ajax无刷新显示
  6. 汇编:MSR/MRS/BIC指令
  7. HDU 3152 Obstacle Course(优先队列,广搜)
  8. Secret of Chocolate Poles (Aizu1378——dp)
  9. php观察折模式
  10. Mybatis操作Mysql批量更新的一个坑-&amp;allowMultiQueries=true允许批量更新