One popular website developed an unusual username editing procedure. One can change the username only by deleting some characters from it: to change the current name s, a user can pick number p and character c and delete the p-th occurrence of characterc from the name. After the user changed his name, he can't undo the change.
For example, one can change name "arca" by removing the second occurrence of character "a" to get "arc".
Polycarpus learned that some user initially registered under nickname t, where t is a concatenation of k copies of string s. Also, Polycarpus knows the sequence of this user's name changes. Help Polycarpus figure out the user's final name.
The first line contains an integer k (1 ≤ k ≤ 2000). The second line contains a non-empty string s, consisting of lowercase Latin letters, at most 100 characters long. The third line contains an integer n (0 ≤ n ≤ 20000) — the number of username changes. Each of the next n lines contains the actual changes, one per line. The changes are written as "pi ci" (without the quotes), where pi (1 ≤ pi ≤ 200000) is the number of occurrences of letter ci, ci is a lowercase Latin letter. It is guaranteed that the operations are correct, that is, the letter to be deleted always exists, and after all operations not all letters are deleted from the name. The letters' occurrences are numbered starting from 1.
Print a single string — the user's final name after all changes are applied to it.
2 bac 3 2 a 1 b 2 c
acb
1 abacaba 4 1 a 1 a 1 c 2 b
baa
Let's consider the first sample. Initially we have name "bacbac"; the first operation transforms it into "bacbc", the second one — to "acbc", and finally, the third one transforms it into "acb".
此题主要思路是:把每个字母的个数和出现位置以线段树的形式存储。
每个字母(共有26个)分别代表一个线段树,线段树的根结点保存该字母总共出现的次数,叶结点(l == r )保存字符出现的位置,每个“字符”线段树共同组成总的线段树,保存的是字符串的信息。
线段树本身用于大量元素的存储以及点或区间的修改(增加/赋值/删除),本题要求删除某个字符的第i次出现,正好可利用线段树解决。
</pre><pre name="code" class="cpp">#include <string.h>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define inf -0x3f3f3f3f
#define mem0(a) memset(a,0,sizeof(a))
#define maxn 200000+10
char s[maxn];
int vis[maxn];
int a[26][maxn<<2];
void Getsum(int ch,int cur){
a[ch][cur]=a[ch][cur<<1]+a[ch][cur<<1|1];
}
void update(int ch,int i,int l,int r,int cur){//这里i代表编号位置,第i个字母
if( l == r){
a[ch][cur]=1;
return ;
}
int mid = ( l + r)>>1 ;
if(i <= mid)
update(ch,i,l,mid,cur<<1);
else
update(ch,i,mid+1,r,cur<<1|1);
Getsum(ch,cur);
}
//删除字符ch的第n个
int deleted(int ch, int n, int l,int r,int cur){//n代表第n个字母ch
if( l == r){
a[ch][cur] = 0 ;
return l ;
}
int mid = ( l + r) >>1 ,ans ;
if(n <= a[t][cur<<1])
ans = deleted()(ch,n,l,mid,cur<<1);
else {
ans = deleted(ch,n -a[ch][cur<<1],mid+1,r,cur<<1|1);
}
Getsum(ch,cur);
return ans ;
}
int main()
{
int k,m;
while(scanf("%d %s%d",&k,s+1,&m)!=EOF){
mem0(vis);mem0(a);
int len = strlen(s+1);
int n = len*k,j,i;
for(j = len+1;--k;){
for( i = 1; i <= len ; i++)
s[j++]=s[i];
}
s[j]=0;
for(int i = 1 ; s[i] ; i++){
update(s[i]-'a',i,1,n,1);
}
char c;
while(m--){
scanf("%d %c",&k,&c);
int num = deleted(c-'a',k,1,n,1);
vis[num]=1;
}
for(int i = 1 ; s[i] ; i++)
if(vis[i]==0)
printf("%c",s[i]);
puts("");
}
return 0;
}