题意:在文本串a中能否找到一个子序列等于字符串bi,有m个询问
对a串预处理一个nxt[i][ch],表示是s[i]以及之后字符 ch 第一次出现的下标,这个预处理就是逆着推,从后面往前面做,每次先把nxt[i+1][ch]赋值给nxt[i][ch],然后再用当前字母更新nxt数组即nxt[i][s[i]] = i;
预处理好后,对于每一个bi,从idx = 0开始看nxt[idx][b[0]]是不是等于-1,如果不是-1,就让idx = nxt[idx][b[0]]+1,再去做b[1],若做完整个b串都没有遇到-1则可以,否则不行;
这题和CF1295C差不多
#include <cstdio> #include <cstring> #include <iostream> using namespace std; const int N = 1e6+10; int nxt[N][26];//s[i]以及之后的第一个c的下标 char s[N]; int main(){ scanf("%s",s); int cas;scanf("%d",&cas); int n = strlen(s); for(int i = 0;i < 26;i++) nxt[n][i] = -1; for(int i = n-1;i >= 0;i--){ for(int c = 0;c < 26;c++) nxt[i][c] = nxt[i+1][c];//其他字符等于s[i+1]以及之后的第一个c下标 nxt[i][s[i]-'a'] = i;//这一位字符等于i } while(cas--){ scanf("%s",s); int m = strlen(s); int idx = 0,flag = 0; bool f = 1; for(int i = 0;i < m;i++){ if(nxt[idx][s[i]-'a']!=-1){ idx = nxt[idx][s[i]-'a']+1; }else{ f = 0; break; } } if(f) puts("Yes"); else puts("No"); } return 0; }