题意:给出一个母串s以及一个空串p,和一个整数q。接下来有q个操作,push c:在p串后面添加一个字符c, pop:删除尾部一个字符。对于每次操作输出p是否为s的子序列(可以不连续)
题解:预处理母串s,使用nex[i][j] 数组来表示第i个字符后面(j+‘a’)字符的第一次出现的位置,然后通过m和len来更新p,如果当前m位置后面存在一个(c-‘a’)字符,那么ans[m] = nex[ans[m]][c - ‘a’] 否则ans[++m] = -1表示不存在匹配的子序列, 删除的时候m–即可,最后要更新一下len = min(len, m),输出答案的时候判断len==m?“YES”:“NO”;
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 10;
const ll inf = 0x3f3f3f3f;
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define per(i, a, b) for(int i = a; i >= b; i--)
#define met(a, b) memset(a, b, sizeof(a))
#define fi first
#define se second
#define pb push_back
#define mp make_pair
ll gcd(ll a, ll b) {return b == 0 ? a : gcd(b, a % b);}
char s[maxn], p[maxn], com[maxn], c[5];
int q, nex[maxn][26], pos[26], len, m = 0, ans[maxn];
bool judge() {
int st = pos[p[0] - 'a'];
if(st == -1) return false;
rep(i, 1, len - 1) {
if(nex[st][(p[i] - 'a')] == -1) return false;
st = nex[st][(p[i] - 'a')];
}
return true;
}
int main() {
//std::ios::sync_with_stdio(false);
while(~scanf("%s %d", s + 1, &q)) {
met(nex, -1);
met(pos, -1);
int l = strlen(s + 1);
per(i, l, 0) {
rep(j, 0, 25) {
nex[i][j] = pos[j];
}
pos[s[i] - 'a'] = i;
}
len = 0, m = 0;
ans[0] = 0;
while(q--) {
scanf("%s", com);
if(com[0] == 'p' && com[1] == 'u') {
scanf("%s", c);
if(ans[m] != -1 && nex[ans[m]][c[0] - 'a'] != -1) ans[m + 1] = nex[ans[m]][c[0] - 'a'], m++, len++;
else ans[++m] = -1;
} else {
m--;
len = min(m, len);
}
if(len == m) puts("YES");
else puts("NO");
}
}
return 0;
}