-
问题:对于一个字符串\(s\),询问\(q\)次:字符串\(t\)是否为\(s\)的子序列.
-
题解:我们记录一个位置\(pos\),遍历\(t\),在\(s\)中二分查找第一个下标大于\(pos\)并且等于\(t[i]\)的位置,更新\(pos\).
如果找不到直接标记一下即可.
-
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <stack> #include <queue> #include <vector> #include <map> #include <set> #include <unordered_set> #include <unordered_map> #define ll long long #define fi first #define se second #define pb push_back #define me memset const int N = 1e6 + 10; const int mod = 1e9 + 7; using namespace std; typedef pair<int,int> PII; typedef pair<long,long> PLL; int t,n,q,m; int x; int pos; vector<int> v[N]; int main() { ios::sync_with_stdio(false); cin>>t>>n>>q>>m; for(int i=1;i<=n;++i){ cin>>x; v[x].pb(i); } while(q--){ int len; cin>>len; pos=0; bool flag=true; while(len--){ cin>>x; if(!flag) continue; auto iter=lower_bound(v[x].begin(),v[x].end(),pos+1); if(iter==v[x].end()) flag=false; else pos=*iter; } if(flag) puts("Yes"); else puts("No"); } return 0; }