同hdu 4749
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NavigableSet;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeSet;
public class Main {
public static void main(String[] args) throws IOException{
StreamTokenizer cin = new StreamTokenizer(new BufferedInputStream(System.in)) ;
InputReader in = new InputReader(System.in) ;
PrintWriter out = new PrintWriter(System.out) ;
while(cin.nextToken() != cin.TT_EOF){
int n = (int) cin.nval ;
cin.nextToken() ; int m = (int) cin.nval ;
cin.nextToken() ; int k = (int) cin.nval ;
new Task().solve(cin , n , m , k , out); // out.flush() ;
}
out.flush() ;
}
}
class Task{
static final int maxn = 100008 ;
static int[] next = new int[maxn] ;
static int[] a = new int[maxn] ;
static int[] b = new int[maxn] ;
static int[][] sa = new int[maxn][26] ;
static int[][] sb = new int[maxn][26] ;
int n , m , k ;
boolean ok1(int i , int j){
int l1 , l2 , e1 , e2 ;
l1 = l2 = e1 = e2 = 0 ;
for(int t = 1 ; t <= k ; t++){
if(t < b[i]){
if(i-j-1>=0) l1 += sb[i][t] - sb[i-j-1][t] ;
else l1 += sb[i][t] ;
}
if(t < b[j])
l2 += sb[j][t] ;
}
if(i-j-1>=0) e1 = sb[i][b[i]] - sb[i-j-1][b[i]] ;
else e1 = sb[i][b[i]] ;
e2 = sb[j][b[j]] ;
return l1==l2 && e1==e2 ;
}
boolean ok2(int i , int j){
int l1 , l2 , e1 , e2 ;
l1 = l2 = e1 = e2 = 0 ;
for(int t = 1 ; t <= k ; t++){
if(t < a[i]){
if(i-j-1>=0) l1 += sa[i][t] - sa[i-j-1][t] ;
else l1 += sa[i][t] ;
}
if(t < b[j])
l2 += sb[j][t] ;
}
if(i-j-1>=0) e1 = sa[i][a[i]] - sa[i-j-1][a[i]] ;
else e1 = sa[i][a[i]] ;
e2 = sb[j][b[j]] ;
return l1==l2 && e1==e2 ;
}
void getNext(){
next[0] = -1 ;
int i = 0 , j = -1 ;
while(i < m){
if(j == -1 || ok1(i , j)) next[++i] = ++j ;
else j = next[j] ;
}
}
int kmp(){
getNext();
if(n == 1 && m == 1){
return ok2(0 , 0) ? 1 : 0 ;
}
int cnt = 0 , j = 0 ;
for(int i = 0 ; i < n ; i++){
while(j > 0 && !ok2(i , j)) j = next[j] ;
if(ok2(i , j)) j++ ;
if(j == m){
cnt++ ;
j = next[j]; // or j = next[j] ;
ids.add(i-m+1) ;
}
}
return cnt ;
}
ArrayList<Integer> ids = new ArrayList<Integer>() ;
void solve(StreamTokenizer cin , int n , int m , int k , PrintWriter out) throws IOException{
this.n = n ;
this.m = m ;
this.k = k ;
for(int i = 0 ; i <= n ; i++) Arrays.fill(sa[i] , 0) ;
for(int i = 0 ; i <= m ; i++) Arrays.fill(sb[i] , 0) ;
for(int i = 0 ; i < n ; i++){
cin.nextToken() ; a[i] = (int)cin.nval ;
}
for(int i = 0 ; i < m ; i++){
cin.nextToken() ; b[i] = (int)cin.nval ;
}
sa[0][a[0]]++ ;
for(int i = 1 ; i < n ; i++){
for(int j = 1 ; j <= k ; j++) sa[i][j] = sa[i-1][j] ;
sa[i][a[i]]++ ;
}
sb[0][b[0]]++ ;
for(int i = 1 ; i < m ; i++){
for(int j = 1 ; j <= k ; j++) sb[i][j] = sb[i-1][j] ;
sb[i][b[i]]++ ;
}
out.println(kmp()) ;
for(int i : ids) out.println(i+1) ;
}
}
class InputReader{
public BufferedReader reader ;
public StringTokenizer tokenizer ;
public InputReader(InputStream stream){
reader = new BufferedReader(new InputStreamReader(stream), 32768) ;
tokenizer = null ;
}
public String next(){
while(tokenizer == null || ! tokenizer.hasMoreTokens()){
try{
tokenizer = new StringTokenizer(reader.readLine());
}catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt(){
return Integer.parseInt(next());
}
public long nextLong(){
return Long.parseLong(next());
}
public double nextDouble(){
return Double.parseDouble(next());
}
}