月月查华华的手机---经典题
思路:
设主串为S,判断模式串是不是S的子序列?
贪心考虑,从左到右扫一遍S,如果当前字符在S中出现,那么我就找到S中最先出现的位置A1,然后我们下次找的位置要大于A1,以此类推。
复杂度分析
二分查找 + 枚举 = O( )
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 5;
vector<int> pos[30];
char s[maxn], tmp[maxn];
int n, m;
bool solve(){
int ind = -1;
for(int i = 1; i <= n; i++){
int f = tmp[i] - 'a';
ind = upper_bound(pos[f].begin(), pos[f].end(), ind) - pos[f].begin();
if(ind == pos[f].end() - pos[f].begin()) return false;
ind = pos[f][ind];
}
return true;
}
int main(){
//pos[0].push_back(1); pos[0].push_back(2); pos[0].push_back(3);
//cout << (upper_bound(pos[0].begin(), pos[0].end(), -1) - pos[0].begin()) << endl;
scanf("%s", s + 1);
n = strlen(s + 1);
for(int i = 1; i <= n; i++){
pos[s[i] - 'a'].push_back(i);
}
scanf("%d", &m);
while(m--){
scanf("%s", tmp + 1);
n = strlen(tmp + 1);
if(solve()){
puts("Yes");
}
else{
puts("No");
}
}
return 0;
}


