yyl说是用链表O(n)做
但是并脑补不出来。
发现可以用个vector记录一下每个数出现的位置,然后对于每个新序列就二分一下,找下一个数出现的离当前位置最近的位置,更新一下当前位置即可。
时间复杂度O(∑ k log k)的,不用卡常也过了。。
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int N=1000005; vector<int> vec[N]; int a[N],b[N],n,m,k,nxt[N]; bool ck(){ scanf("%d",&k); int pos=0; for(int i=1;i<=k;i++) scanf("%d",&b[i]),nxt[b[i]]=0; for(int i=1;i<=k;i++) { nxt[b[i]]=upper_bound(vec[b[i]].begin(),vec[b[i]].end(),pos)-vec[b[i]].begin(); if(nxt[b[i]]==vec[b[i]].size()) return 0; pos=vec[b[i]][nxt[b[i]]]; } return 1; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]),vec[a[i]].push_back(i); scanf("%d",&m); for(int i=1;i<=m;i++) puts(ck()?"TAK":"NIE"); return 0; }