hdu5489

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) ;  

           int t = in.nextInt() ;
           for(int cas = 1 ; cas <= t ; cas++){
                 out.print("Case #" + cas + ": ") ;
                 new Task().solve(in, out) ;
           }

           out.flush() ;

    }

}

class  Task{

       static  final  int N = 100008 ;
       static  int[]  num = new int[N] ;
       static  int[]  uninum = new int[N] ;
       static  int[]  tail = new int[N] ;
       static  int[]  head = new int[N] ;
       static  int[]  que = new int[N] ;

       void   solve(InputReader in , PrintWriter out){
              int n = in.nextInt() ; 
              int L = in.nextInt() ;

              for(int i = 1 ; i <= n ; i++) num[i] = uninum[i] = in.nextInt() ;

              int m = unique(uninum , 1 , n) ;

              Arrays.fill(que, Integer.MAX_VALUE) ;

              for(int i = 1 ; i <= n ; i++){
                    int d = lower_bound(que, 1 , m , num[i])   ; 
                    tail[i] = d ;
                    que[d] = num[i] ;
              }

              Arrays.fill(que, Integer.MAX_VALUE) ;
              for(int i = n ; i >= 1 ; i--){
                    int d = lower_bound(que, 1 , m , -num[i])   ; 
                    head[i] = d ;
                    que[d] = -num[i] ;
              }

              Arrays.fill(max, 0) ;

              int ans = 0 ;
              num[n+1] = Integer.MAX_VALUE ;
              head[n+1] = 0 ;
              for(int i = L+1 ; i <= n+1 ; i++){
                    int id = lower_bound(uninum, 1, m, num[i]) ;
                    ans = Math.max(ans, ask(0 , id-1 , 0 , m , 1) + head[i]) ;
                    id = lower_bound(uninum, 1, m, num[i-L]) ;
                    if(i <= n) update(id, tail[i-L], 0, m, 1) ;
              }

              out.println(ans) ;

       }   

       int   lower_bound(int[] a , int _l , int _r , int d){
             int l = _l  , r = _r  ,  m  , s = -1 ;
             if(a[_l] > d) return _l  ;
             if(a[_r] < d) return _r + 1 ;
             while(l <= r){
                  m = (l + r) >> 1 ;
                  if(a[m] >= d){
                       s = m ;
                       r = m-1 ;
                  }
                  else l = m+1 ;
             }
             return s ;
       }

       int  unique(int[] a , int _l , int _r){
            Arrays.sort(a , _l , _r+1) ;
            int id = _l ;
            for(int i = _l ; i <= _r ; i++){
                 if(a[i] == a[id]) continue ;
                 else a[++id] = a[i] ;
            }
            return id ;
       }   




       static  int[] max = new int[N<<2] ;

       void  update(int id , int val , int l , int r , int root){
             if(l == r){
                    max[root] = Math.max(max[root], val) ;
                    return ;
             } 
             int m = (l + r) >> 1 ;
             if(id <= m)  update(id, val, l, m, root<<1) ;
             else  update(id, val, m+1, r, root<<1|1) ;
             max[root] = Math.max(max[root<<1], max[root<<1|1]) ;
       }

       int  ask(int al , int ar , int l ,  int r ,  int root){
           // System.out.println(al + " " + ar + " " + l + " " + r);
            if(al <= l && r <= ar) return max[root] ;
            int m = (l + r) >> 1 ;
            int s = Integer.MIN_VALUE ;
            if(al <= m) s = Math.max(s, ask(al , ar , l , m , root<<1)) ;
            if(ar > m)  s = Math.max(s, ask(al , ar, m+1, r, root<<1|1)) ;
            return s ;
       }
} 

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

}

你可能感兴趣的:(hdu5489)