这道题就是每次询问确定最初的l,r然后l向右移动并维护r使得m个数总是包括,求最短区间就行
#include <iostream>
#include <cstring>
#define inf 210000000
#define Max 100010
using namespace std;
int main()
{
int s[Max],num[Max],p[Max],mark[Max];
int N,M,Q,a;
while(cin>>N>>M&&(N|M))
{
memset(mark,0,sizeof(mark));
memset(p,-1,sizeof(p));
for(int i=0;i<N;i++)
{
cin>>s[i];
if(p[s[i]]==-1)p[s[i]]=i;
}
s[N]=N;
for(int i=1;i<=M;i++)
{
cin>>Q;
int l=N,r=-1,len=inf;
for(int j=0;j<Q;j++)
{
cin>>a;
num[a]=0;//num没有初始化过
mark[a]=i;
if(p[a]>r)r=p[a];
if(p[a]<l)l=p[a];
}
for(int j=l;j<=r;j++)++num[s[j]];
len=r-l+1;
while(r<N)
{
--num[s[l]];
if(num[s[l]]==0)
{
while(++r<N&&s[r]!=s[l])num[s[r]]++;
num[s[r]]=1;
}
while(++l<=r&&mark[s[l]]!=i);
if(r<N&&len>r-l+1)len=r-l+1;
}
cout<<len<<endl;
}
}
return 0;
}