题意:找到间隔为p的连续序列,使得可以经过调序得到第二个序列。
思路:就是一个个地找……每次向右走一个间隔,同时删除左边的那个,保证l到r的长度为m,再判断。
AC代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
map<int,int> match1,match2;
int num1[200010],ans[200010],num;
long long n,len,m;
void solve(long long l)
{ long long r=l+len*(m-1),i,j,k;
if(r>n)
return;
for(i=0;i<m;i++)
{ k=num1[l+i*len];
match1[k]++;
if(match2[k]>=match1[k])
num++;
}
if(num==m)
{ ans[0]++;
ans[ans[0]]=l;
}
l+=len;r+=len;
while(r<=n)
{ k=num1[l-len];
match1[k]--;
if(match2[k]>match1[k])
num--;
k=num1[r];
match1[k]++;
if(match2[k]>=match1[k])
num++;
if(num==m)
{ ans[0]++;
ans[ans[0]]=l;
}
l+=len;r+=len;
}
}
int main()
{ int i,j,k;
scanf("%I64d%I64d%I64d",&n,&m,&len);
for(i=1;i<=n;i++)
scanf("%d",&num1[i]);
for(i=1;i<=m;i++)
{ scanf("%d",&k);
match2[k]++;
}
for(i=1;i<=len;i++)
{ match1.clear();
num=0;
solve(i);
}
k=ans[0];
sort(ans+1,ans+1+k);
printf("%d\n",k);
if(k>0)
{ printf("%d",ans[1]);
for(i=2;i<=k;i++)
printf(" %d",ans[i]);
}
printf("\n");
}