http://codeforces.com/gym/101755/problem/L
题解:栈模拟+二分
题意就是 给你一个主串,一个空串,给你一系列操作让你确定操作后的串是否是主串的子序列。
1、 push a 这个串后添加一个字母
2、pop 这个串后删除最后一个字母
首先预处理主串的每个字母所有出现的位置,然后开始操作,每次操作都完了都把该字母在主串中对应的下标压进栈 意思是拼接的内个串,然后就是每次操作串后判断就是二分该字母出现的位置是否在预处理主串的该字母的数组中且得大于栈顶字母的下标即可,若不满足以上条件则压栈-1,表示该字母以后都不可能为子序列,等待pop吧
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
#include<vector>
#include<stack>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1000000;
vector<int> v[30];
stack<int> ss;
int main(){
string s;
cin>>s;
int len=s.size();
for(int i=0;i<len;i++){
v[s[i]-'a'].push_back(i);
}
int n;
cin>>n;
while(n--){
string a;
string b;
cin>>a;
if(a[1]=='o'){
if(ss.empty()){
cout<<"YES"<<endl;
continue;
}
ss.pop();
if(ss.empty()){
cout<<"YES"<<endl;
continue;
}
if(ss.top()==-1){
cout<<"NO"<<endl;
}
else{
cout<<"YES"<<endl;
}
}
if(a[1]=='u'){
cin>>b;
if(ss.empty()){
if(v[b[0]-'a'].size()==0){
cout<<"NO"<<endl;
ss.push(-1);
}
else{
cout<<"YES"<<endl;
ss.push(v[b[0]-'a'][0]);
}
continue;
}
if(v[b[0]-'a'].size()==0){//栈不为空但没有改元素
cout<<"NO"<<endl;
ss.push(-1);
continue;
}
if(ss.top()==-1){
cout<<"NO"<<endl;
ss.push(-1);
continue;
}
// cout<<ss.top()<<endl<<endl;
int pos=upper_bound (v[b[0]-'a'].begin(),v[b[0]-'a'].end(),ss.top()) -v[b[0]-'a'].begin();
//pos 为下标
//cout<<pos<<endl;
int lsize=v[b[0]-'a'].size();
// cout<<lsize<<endl;
if(pos!=lsize){
cout<<"YES"<<endl;
ss.push(v[b[0]-'a'][pos]);
continue;
}
else{
cout<<"NO"<<endl;
ss.push(-1);
}
}
}
}