[DP + 序列自动机] 修改子串并询问原串中是否包含子串 CF1150D

32 篇文章 0 订阅

D. Three Religions

time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

During the archaeological research in the Middle East you found the traces of three ancient religions: First religion, Second religion and Third religion. You compiled the information on the evolution of each of these beliefs, and you now wonder if the followers of each religion could coexist in peace.

The Word of Universe is a long word containing the lowercase English characters only. At each moment of time, each of the religion beliefs could be described by a word consisting of lowercase English characters.

The three religions can coexist in peace if their descriptions form disjoint subsequences of the Word of Universe. More formally, one can paint some of the characters of the Word of Universe in three colors: 11, 22, 33, so that each character is painted in at most one color, and the description of the ii-th religion can be constructed from the Word of Universe by removing all characters that aren't painted in color ii.

The religions however evolve. In the beginning, each religion description is empty. Every once in a while, either a character is appended to the end of the description of a single religion, or the last character is dropped from the description. After each change, determine if the religions could coexist in peace.

Input

The first line of the input contains two integers n,qn,q (1≤n≤1000001≤n≤100000, 1≤q≤10001≤q≤1000) — the length of the Word of Universe and the number of religion evolutions, respectively. The following line contains the Word of Universe — a string of length nn consisting of lowercase English characters.

Each of the following line describes a single evolution and is in one of the following formats:

  • + ii cc (i∈{1,2,3}i∈{1,2,3}, c∈{a,b,…,z}c∈{a,b,…,z}: append the character cc to the end of ii-th religion description.
  • - ii (i∈{1,2,3}i∈{1,2,3}) – remove the last character from the ii-th religion description. You can assume that the pattern is non-empty.

You can assume that no religion will have description longer than 250250 characters.

Output

Write qq lines. The ii-th of them should be YES if the religions could coexist in peace after the ii-th evolution, or NO otherwise.

You can print each character in any case (either upper or lower).

Examples

input

Copy

6 8
abdabc
+ 1 a
+ 1 d
+ 2 b
+ 2 c
+ 3 a
+ 3 b
+ 1 c
- 2

output

Copy

YES
YES
YES
YES
YES
YES
NO
YES

input

Copy

6 8
abbaab
+ 1 a
+ 2 a
+ 3 a
+ 1 b
+ 2 b
+ 3 b
- 1
+ 2 z

output

Copy

YES
YES
YES
YES
YES
NO
YES
NO

Note

In the first example, after the 6th evolution the religion descriptions are: ad, bc, and ab. The following figure shows how these descriptions form three disjoint subsequences of the Word of Universe:

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int mn = 100010;

char ch[mn];
int nx[mn][30], len[5], dp[255][255][255];
int str[5][255], down[5];
int main()
{
    int n, q;   scanf("%d %d", &n, &q);
    scanf("%s", ch + 1);
    
    /// 序列自动机
    /// 处理每个位置之后每种字母第一次出现的位置
    for (int i = 0; i < 26; i++)
        nx[n][i] = n + 1, nx[n + 1][i] = n + 1;
    for (int i = n; i >= 0; i--)
    {
        for (int j = 0; j < 26; j++)
            nx[i][j] = nx[i + 1][j];
        nx[i][ch[i + 1] - 'a'] = i + 1;
    }
    ///
    
    while (q--)
    {
        char op[5]; int id; char c[5];
        scanf("%s", op);
        if (op[0] == '+')
        {
            scanf("%d %s", &id, c);
            str[id][++len[id]] = c[0] - 'a';
            for (int i = 1; i <= 3; i++)
                down[i] = (id == i) ? len[i] : 0;
            for (int i = down[1]; i <= len[1]; i++)
            {
                for (int j = down[2]; j <= len[2]; j++)
                {
                    for (int k = down[3]; k <= len[3]; k++)
                    {
                        dp[i][j][k] = n + 1;
                        if (i)  dp[i][j][k] = min(dp[i][j][k], nx[dp[i - 1][j][k]][str[1][i]]);
                        if (j)  dp[i][j][k] = min(dp[i][j][k], nx[dp[i][j - 1][k]][str[2][j]]);
                        if (k)  dp[i][j][k] = min(dp[i][j][k], nx[dp[i][j][k - 1]][str[3][k]]);
                    }
                }
            }
        }
        else if (op[0] == '-')
        {
            scanf("%d", &id);
            len[id]--;
        }
        
        if (dp[len[1]][len[2]][len[3]] > n) printf("NO\n");
        else    printf("YES\n");
    }
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值