L - Queries on a String Gym - 101755L

题意:给出一个母串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;
}

猜你喜欢

转载自blog.csdn.net/m0_38081836/article/details/81320304