解法:这题就是kmp匹配过程中用树状数组维护每个数字出现的次数,快速查询在前面比自己小的和等于自己的来判断是否能向后匹配
///BZOJ 1461
///KMP + BIT
#include <bits/stdc++.h>
using namespace std;
const int maxn = 500010;
const int maxs = 10010;
int n, k, s;
int a[maxn], b[maxn], fail[maxn];
int rnk1[maxn], rnk2[maxn];
vector <int> ans;
int c[maxn];
inline int lowbit(int x){return x&-x;}
inline void add(int x, int v){for(int i=x; i<=s; i+=lowbit(i)) c[i]+=v;}
inline int query(int x){
if(x==0) return 0;
int ret = 0;
for(int i=x; i; i-=lowbit(i)) ret += c[i];
return ret;
}
inline void kmp(){
}
int main(){
scanf("%d%d%d", &n,&k,&s);
for(int i=1; i<=n; i++) scanf("%d", &a[i]);
for(int i=1; i<=k; i++) scanf("%d", &b[i]), add(b[i], 1), rnk1[i]=query(b[i]), rnk2[i]=query(b[i]-1);
int i, j, m;
fail[1]=j=0;
memset(c, 0, sizeof(c));
for(int i=2; i<=k; i++){
add(b[i], 1);
while(j&&(query(b[i])!=rnk1[j+1]||query(b[i]-1)!=rnk2[j+1])){
for(m=i-j; m<i-fail[j]; m++) add(b[m],-1);
j=fail[j];
}
fail[i] =j+=(query(b[i])==rnk1[j+1]) && (query(b[i]-1)==rnk2[j+1]);
}
j = 0;
memset(c, 0, sizeof(c));
for(int i=1; i<=n; i++){
add(a[i], 1);
while(j&&(query(a[i])!=rnk1[j+1]||query(a[i]-1)!=rnk2[j+1])){
for(m=i-j; m<i-fail[j]; m++) add(a[m],-1);
j=fail[j];
}
if(j==k-1){
ans.push_back(i-j);
for(m=i-j; m<i-fail[j]; m++) add(a[m],-1);
j=fail[j];
}
++j;
}
int tot = ans.size();
printf("%d\n", tot);
for(int i=0; i<tot; i++){
printf("%d\n", ans[i]);
}
return 0;
}