poj3167

同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());
        }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值