题目大意:给定序列A,多次询问某个序列B是不是A的子序列
设某个序列B当前需要匹配的元素是x,那么就将所有x相同的B序列存成一个链表放在head[x]上
然后对于A的每个元素x,去head[x]上撸一遍链表,更新这些B序列的当前元素即可
时间复杂度是线性的 不过为毛跑的这么慢= =
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 1001001
using namespace std;
struct List{
vector<int> seq;
int belong;
List *next;
void* operator new (size_t)
{
static List *mempool,*C;
if(mempool==C)
mempool=(C=new List[1<<16])+(1<<16);
return C++;
}
}*head[M];
int n,m,k;
int a[M],b[M];
bool ans[M];
int main()
{
int i,j;
cin>>n;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
cin>>m;
for(i=1;i<=m;i++)
{
scanf("%d",&k);
for(j=1;j<=k;j++)
scanf("%d",&b[j]);
List *temp=new List;
for(j=k;j;j--)
temp->seq.push_back(b[j]);
temp->belong=i;
temp->next=head[temp->seq.back()];
head[temp->seq.back()]=temp;
}
for(i=1;i<=n;i++)
{
List *temp=head[a[i]],*next;head[a[i]]=0x0;
for(;temp;temp=next)
{
next=temp->next;
temp->seq.pop_back();
if(temp->seq.empty())
ans[temp->belong]=true;
else
{
temp->next=head[temp->seq.back()];
head[temp->seq.back()]=temp;
}
}
}
for(i=1;i<=m;i++)
puts(ans[i]?"TAK":"NIE");
return 0;
}