写到这里KMP应该马马虎虎算懂了。。。觉得这道题难点不在KMP上,并且很惭愧,难得那个点不是自己想出来的
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 25555
int occur[30];
int low[maxn],high[maxn],next[maxn],a[maxn];
int b[111111],ans[111111];
bool cmp(int *a,int *b,int k){
if(b[occur[a[k]]]!=b[k]) return false;
if(low[k]>=0&&b[low[k]]>=b[k]) return false;
if(high[k]>=0&&b[high[k]]<=b[k]) return false;
return true;
}
void get_next(int l){
int j=-1,i;
next[0]=-1;
for(i=1;i<l;i++){
while(j>=0&&!cmp(a,a+(i-j-1),j+1)) j=next[j];
if(cmp(a,a+(i-j-1),j+1)) j++;
next[i]=j;
}
}
int kmp(int l,int k){
int j=-1,i,t=0;
for(i=0;i<l;i++){
while(j>=0&&!cmp(a,b+(i-j-1),j+1)) j=next[j];
if(cmp(a,b+(i-j-1),j+1)) j++;
if(j+1==k){
ans[t++]=i-j+1;
j=next[j];
}
}
return t;
}
int main(){
int n,k,s;
int i,j,t;
while(~scanf("%d%d%d",&n,&k,&s)){
for(i=0;i<n;i++)
scanf("%d",&b[i]);
for(i=1;i<=s;i++)
occur[i]=-1;
occur[0]=occur[s+1]=-2;
for(i=0;i<k;i++){
scanf("%d",&a[i]);
if(occur[a[i]]==-1) occur[a[i]]=i;
for(j=a[i]-1;occur[j]==-1;j--);
low[i]=occur[j];
for(j=a[i]+1;occur[j]==-1;j++);
high[i]=occur[j];
}
get_next(k);
t=kmp(n,k);
printf("%d\n",t);
for(i=0;i<t;i++)
printf("%d\n",ans[i]);
}
}