Description
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: 1, 2, 3, so that each character is painted in at most one color, and the description of the i-th religion can be constructed from the Word of Universe by removing all characters that aren’t painted in color i.
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,q (1≤n≤100000, 1≤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 n consisting of lowercase English characters.
Each of the following line describes a single evolution and is in one of the following formats:
- i c i∈{1,2,3}, c∈{a,b,…,z}: append the character c to the end of i-th religion description.
- i (i∈{1,2,3}) – remove the last character from the i-th religion description. You can assume that the pattern is non-empty.
You can assume that no religion will have description longer than 250 characters.
Output
Write q lines. The i-th of them should be YES if the religions could coexist in peace after the i-th evolution, or NO otherwise.
You can print each character in any case (either upper or lower).
Examples
Input
6 8
abdabc
- 1 a
- 1 d
- 2 b
- 2 c
- 3 a
- 3 b
- 1 c
- 2
Output
YES
YES
YES
YES
YES
YES
NO
YES
Input
6 8
abbaab
- 1 a
- 2 a
- 3 a
- 1 b
- 2 b
- 3 b
- 1
- 2 z
Output
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:
题意:
给出一个长度为n的字符串s和三个空串a,b,c,进行q次操作,每次操作会选择abc中的某一个,在最后添加一个字符x(用+表示),或者删掉最后一个字符(用-表示)。问每次操作之后,s中能否找到不重叠的三个子序列abc,能输出YES,不能输出NO。
解法:
完全没想到字符串dp还能这么用,我只配解说大佬的代码=m=。
首先建立一个数组nex[i][j],代表从字符串s的第i位起一直到第n位,字母j出现的第一个位置。再建立一个数组dp[i][j][k],代表匹配了a串前i位字符,b串前j位字符和c串前k位字符的时候,最后一个字符在s中的位置。
遇到操作+的时候,首先判断是对哪个串进行添加,对于它只需要枚举最后一位,因为之前匹配好的dp[i][j][k]其实都没有变化,其余两个串枚举全长。
因为最后一个字符可以来自abc中的任何一个,所以每次枚举都要进行三个判断取min操作。
遇到操作-的时候,直接把串的长度-1就可以了,答案会自动向前推。
如果dp[len[1]][len[2]][len[3]]>n,表明匹配位置超过了s的长度,那么输出NO,否则就是YES。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stdlib.h>
#include<cstring>
using namespace std;
int n,q,now,pos;
int len[3+5],nex[100000+5][26+5];
int dp[255+5][255+5][255+5];
char op1[5],op2[5];
char s[100000+5],ss[3+5][100000+5];
int main()
{
scanf("%d%d%s",&n,&q,s+1);
memset(dp,0x3f,sizeof dp);
dp[0][0][0]=0;
for(int i=0;i<=26;i++) nex[n+1][i]=nex[n+2][i]=n+1;
s[0]=0;
for(int i=n;i>=0;i--) {
now=s[i]-'a';
for(int j=0;j<26;j++) {
if(j==now)nex[i][j]=i;
else nex[i][j]=nex[i+1][j];
}
}
while(q--){
scanf("%s",op1+1);
if(op1[1]=='+'){
scanf("%d%s",&pos,op2+1);
ss[pos][++len[pos]]=op2[1];
for(int i=(1==pos?len[1]:0);i<=len[1];i++){
for(int j=(2==pos?len[2]:0);j<=len[2];j++){
for(int k=(3==pos?len[3]:0);k<=len[3];k++){
dp[i][j][k]=n+1;
if(i) dp[i][j][k] = min(dp[i][j][k],nex[dp[i-1][j][k]+1][ss[1][i]-'a']);
if(j) dp[i][j][k] = min(dp[i][j][k],nex[dp[i][j-1][k]+1][ss[2][j]-'a']);
if(k) dp[i][j][k] = min(dp[i][j][k],nex[dp[i][j][k-1]+1][ss[3][k]-'a']);
}
}
}
}else{
scanf("%d",&pos);
len[pos]--;
}
if(dp[len[1]][len[2]][len[3]]>n)printf("NO\n");
else printf("YES\n");
}
return 0;
}