Queries on a String

本文介绍了一种使用栈模拟和二分查找算法来判断一系列操作后生成的字符串是否为主串的子序列的方法。通过预处理主串字符位置,每次操作更新栈并检查字符位置,确保生成串符合子序列条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);
			}		
		}
	}
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值