Description
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 character c 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.
Input
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 "pici" (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.
Output
Print a single string — the user's final name after all changes are applied to it.
Sample Input
2 bac 3 2 a 1 b 2 c
acb
1 abacaba 4 1 a 1 a 1 c 2 b
baa
一开始没什么思路,看到有人用线段树,居然还看到了暴力解法。。。
暴力解法如下 CF跑了1372ms 规定是3S内
思路是:先把字符串都连成一个长string 然后扫一遍 把每个字母出现的位置插入到 对应字母的vector
最后对于每一个操作 p,c 找到字母c的vector 然后读取第p位 得到该字母在原string的位置,标记掉,然后把第p位从vector中删除
最后输出全部没标记的字母就ok
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std;
bool vis [200005];
vector<int> orz[27];
int main()
{
int n,k;
int i,j;
string tm,s;
cin>>k;
cin>>s;
tm+=' '; //下标从一开始;
for (i=1;i<=k;i++)
tm+=s;
for (i=1;i<tm.size();i++) //size比实际string多一个' ' 所以小于号
{
orz[tm[i]-'a'+1].push_back(i); //按出现先后记录每个字母出现的位置
}
cin>>n;
int p;
char cha;
for (i=1;i<=n;i++)
{
scanf("%d %c",&p,&cha);
vis[orz[cha-'a'+1][p-1]]=1; //标记该字母对应的string的位置
orz[cha-'a'+1].erase(orz[cha-'a'+1].begin()+p-1); //删除该位置
}
for (i=1;i<tm.size();i++)
{
if (!vis[i])
printf("%c",tm[i]);
}
printf("\n");
return 0;
}