let for_range s e step f =
  let rec loop i =
    if i <= e then begin f i;loop (i + step) end
  in loop s;;

let sieve num =
  let p = Array.make (num+1) 1 in
  let rec loop i m =
    if i*i < num then
      begin
        if p.(i) = 1 then for_range (i*i) num (i*2) (fun x -> p.(x) <- 0);
        loop (i+m) (if m = 2 then 4 else 2)
      end
  in
  p.(0) <- 0; p.(1)<-(0);
  for_range 4 num 2 (fun x -> p.(x) <- 0);
  for_range 9 num 6 (fun x -> p.(x) <- 0);
  loop 5 2;
  for i = 3 to num-1 do
    p.(i) <- p.(i) + p.(i-1);
  done;
  p
;;

let _ =
  let p = sieve 1000000 in
  let rec read () =
    try let n = read_int () in
        Printf.printf "%d\n" p.(n);
        read ()
    with End_of_file -> ()
  in read ()
;;

Global OOD problem IDs are disjoint from train, validation, and in-distribution test problem IDs.

Prime Number

Write a program which reads an integer n and prints the number of prime numbers which are less than or equal to n. A prime number is a natural number which has exactly two distinct natural number divisors: 1 and itself. For example, the first four prime numbers are: 2, 3, 5 and 7.

Input

Input consists of several datasets. Each dataset has an integer n (1 ≤ n ≤ 999,999) in a line.

The number of datasets is less than or equal to 30.

Output

For each dataset, prints the number of prime numbers.

Sample Input

10
3
11

Output for the Sample Input

4
2
5

Submitted source-code file size, in bytes.

Execution CPU time reported by official Project CodeNet metadata, in milliseconds.

Peak memory usage reported by official Project CodeNet metadata, in kilobytes.


let mod_exp x n m =
  let rec aux acc x = function
      0 -> acc
    | n ->
      aux
        (match n land 1 with
         | 1 -> (acc * x) mod m
         | _ -> acc)
        ((x * x) mod m)
        (n asr 1)
  in
  aux 1 x n

let div_pow_2 n =
  let rec aux s d = match d mod 2 with
      0 -> aux (s+1) (d/2)
    | _ -> s,d
  in aux 0 n

let miller_rabin n a =
  let s,d = div_pow_2 (n-1) in
  let a_exp_d = mod_exp a d n in
  let double x = mod_exp x 2 n in
  let rec loop e = function
      0 -> false
    | i ->
      match e with
        r when r = n - 1 -> true
      | r -> loop (double e) (i-1)
  in
  a_exp_d = 1 || loop a_exp_d s

let miller_rabin_test n k =
  let rec loop = function
      0 -> true
    | i ->
      let a = Random.int (n-1) |> (+) 1 in
      match miller_rabin n a with
        true -> loop (i-1)
      | false -> false
  in loop k

let count_primes n =
  let count = ref 0 in
  for x = 2 to n do
    match miller_rabin_test x 20 with
      true -> count := !count + 1
    | false -> ()
  done;
  !count

let () =
  try
    while true do
      let n = read_int () in
      Printf.printf "%d\n" (count_primes n)
    done
  with
    End_of_file -> ()


let lcs x y =
  let m = String.length x in
  let n = String.length y in
  let dp = Array.make_matrix (m+1) (n+1) 0 in
  for i = 1 to m do
    for j = 1 to n do
      dp.(i).(j) <-
        if x.[i-1] = y.[j-1] then dp.(i-1).(j-1) + 1
        else if dp.(i-1).(j) > dp.(i).(j-1) then dp.(i-1).(j)
        else dp.(i).(j-1)
    done
  done;
  dp.(m).(n)

let () =
  let q = read_int () in
  let rec doit i =
    if i < q then begin
      let x = read_line () in
      let y = read_line () in
      Printf.printf "%d\n" (lcs x y);
      doit (i + 1)
    end in
  doit 0

MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Longest Common Subsequence

For given two sequences $X$ and $Y$, a sequence $Z$ is a common subsequence of $X$ and $Y$ if $Z$ is a subsequence of both $X$ and $Y$. For example, if $X = \{a,b,c,b,d,a,b\}$ and $Y = \{b,d,c,a,b,a\}$, the sequence $\{b,c,a\}$ is a common subsequence of both $X$ and $Y$. On the other hand, the sequence $\{b,c,a\}$ is not a longest common subsequence (LCS) of $X$ and $Y$, since it has length 3 and the sequence $\{b,c,b,a\}$, which is also common to both $X$ and $Y$, has length 4. The sequence $\{b,c,b,a\}$ is an LCS of $X$ and $Y$, since there is no common subsequence of length 5 or greater.

Write a program which finds the length of LCS of given two sequences $X$ and $Y$. The sequence consists of alphabetical characters.

Input

The input consists of multiple datasets. In the first line, an integer $q$ which is the number of datasets is given. In the following $2 \times q$ lines, each dataset which consists of the two sequences $X$ and $Y$ are given.

Output

For each dataset, print the length of LCS of $X$ and $Y$ in a line.

Constraints

$1 \leq q \leq 150$

$1 \leq$ length of $X$ and $Y$ $\leq 1,000$

$q \leq 20$ if the dataset includes a sequence whose length is more than 100

Sample Input 1

3
abcbdab
bdcaba
abc
abc
abc
bc

Sample Output 1

4
3
2

Reference

Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.


let lcs x y =
  let m = String.length x in
  let n = String.length y in
  let dp = Array.make_matrix (m + 1) (n + 1) 0 in
  for i = 1 to m do
    for j = 1 to n do
      dp.(i).(j) <-
        if x.[i-1] = y.[j-1] then dp.(i-1).(j-1) + 1
        else
          let x = dp.(i-1).(j) in
          let y = dp.(i).(j-1) in
          max x y;
    done
  done;
  dp.(m).(n)

let () =
  let q = read_int () in
  for _ = 0 to q - 1 do
    let x = read_line () in
    let y = read_line () in
    lcs x y |> Printf.printf "%d\n"
  done


let lcs s1 s2 =
  let l1 = String.length s1 in
  let l2 = String.length s2 in
  let dp = Array.make_matrix (l1+1) (l2+1) 0 in
  let rec iter i j =
    if i = l1 + 1 then dp.(l1).(l2)
    else if j = l2 + 1 then iter (i+1) 1
    else begin
        if s1.[i-1] = s2.[j-1] then
          dp.(i).(j) <- dp.(i-1).(j-1) + 1
        else
          dp.(i).(j) <- max dp.(i-1).(j) dp.(i).(j-1);
        iter i (j+1)
      end
  in iter 1 1

let () =
  let n = read_int () in
  let rec iter i =
    if i = 0 then ()
    else
      let s1 = read_line () in
      let s2 = read_line () in
      lcs s1 s2 |> string_of_int |> print_endline;
      iter (i-1)
  in iter n


let split_on_char sep s =
  let open String in
  let r = ref [] in
  let j = ref (length s) in
  for i = length s - 1 downto 0 do
    if get s i = sep then begin
      r := sub s (i + 1) (!j - i - 1) :: !r;
      j := i
    end
  done;
  sub s 0 !j :: !r

let dfs vs n =
  let d = Array.make n (-1) in
  let rec doit i j =
    d.(i) <- j;
    List.iter (fun v -> if d.(v) = (-1) then doit v j) vs.(i) in
  Array.iteri (fun i e -> if e = (-1) then doit i i) d;
  d

let () =
  let read_ints () = read_line () |> split_on_char ' ' |>  List.map int_of_string in
  let (n, m) = match read_ints () with
    | [n; m] -> (n, m)
    | _ -> assert false in
  let vs = Array.make n [] in
  for _ = 0 to m - 1 do
    match read_ints () with
    | [s; t] ->
      vs.(s) <- t :: vs.(s);
      vs.(t) <- s :: vs.(t);
    | _ -> assert false
  done;
  let d = dfs vs n in
  let q = read_int () in
  for _ = 0 to q - 1 do
    match read_ints () with
    | [s; t] -> Printf.printf (if d.(s) = d.(t) then "yes\n" else "no\n")
    | _ -> assert false
  done

MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Connected Components

Write a program which reads relations in a SNS (Social Network Service), and judges that given pairs of users are reachable each other through the network.

Input

In the first line, two integer $n$ and $m$ are given. $n$ is the number of users in the SNS and $m$ is the number of relations in the SNS. The users in the SNS are identified by IDs $0, 1, ..., n-1$.

In the following $m$ lines, the relations are given. Each relation is given by two integers $s$ and $t$ that represents $s$ and $t$ are friends (and reachable each other).

In the next line, the number of queries $q$ is given. In the following $q$ lines, $q$ queries are given respectively. Each query consists of two integers $s$ and $t$ separated by a space character.

Output

For each query, print "yes" if $t$ is reachable from $s$ through the social network, "no" otherwise.

Constraints

$2 \leq n \leq 100,000$

$0 \leq m \leq 100,000$

$1 \leq q \leq 10,000$

Sample Input

10 9
0 1
0 2
3 4
5 7
5 6
6 7
6 8
7 8
8 9
3
0 1
5 9
1 3

Sample Output

yes
yes
no


open Printf
open Scanf

let () =
  let n, m = scanf "%d %d " (fun x y -> (x, y)) in
  let g = Array.make n [] in
  let rec set_graph x =
    if x = 0 then ()
    else begin
        let u, v = scanf "%d %d " (fun x y -> (x, y)) in
        g.(u) <- v :: g.(u);
        g.(v) <- u :: g.(v);
        set_graph (x-1)
      end
  in
  let friend u v =
    let que = Queue.create () in
    let vt = Array.make n true in
    let rec loop () =
      if Queue.is_empty que then false
      else let i = Queue.pop que in
           if i = v then true
           else begin
               List.iter (fun j ->
                          if vt.(j) then begin
                              Queue.push j que;
                              vt.(j) <- false
                            end) g.(i);
               loop ()
             end
    in
    Queue.push u que;
    vt.(u) <- false;
    loop ()
  in
  let rec iter x =
    if x = 0 then ()
    else begin
        let u, v = scanf "%d %d " (fun x y -> (x, y)) in
        printf "%s\n" (if friend u v then "yes" else "no");
        iter (x-1)
      end
  in
  set_graph m;
  let q = scanf "%d " (fun x -> x) in
  iter q


module MakeBinaryHeap (M : sig type t val compare : t -> t -> int end) = struct

  type t = { node : M.t array; mutable size : int }

  let make n (init : M.t) = { node = Array.make n init; size = 0 }

  let empty_p t = if t.size = 0 then true else false

  let pop t =
    if t.size <= 0 then failwith "out of size" else
    let rec max_heapify i =
      let l = 2*i in
      let r = 2*i + 1 in
      let m = if l <= t.size && M.compare t.node.(l) t.node.(i) > 0 then l else i in
      let m = if r <= t.size && M.compare t.node.(r) t.node.(m) > 0 then r else m in
      if m = i then ()
      else begin
        let tmp = t.node.(i) in
        t.node.(i) <- t.node.(m);
        t.node.(m) <- tmp;
        max_heapify m
      end in
    let ret = t.node.(1) in
    t.node.(1) <- t.node.(t.size);
    t.size <- t.size - 1;
    max_heapify 1;
    ret

  let push x t =
    let parent i = int_of_float (floor (float_of_int i) /. 2.) in
    let rec doit i =
      let p = parent i in
      if i <= 1 || M.compare t.node.(p) t.node.(i) >= 0 then ()
      else begin
        let tmp = t.node.(i) in
        t.node.(i) <- t.node.(p);
        t.node.(p) <- tmp;
        doit p
      end in
    t.size <- t.size + 1;
    t.node.(t.size) <- x;
    doit t.size

end

module H = MakeBinaryHeap(struct type t = (int * int) let compare (_, x) (_, y) = y - x end)

let dijkstra g n =
  let reached_p = Array.make n false in
  let min_costs = Array.make n max_int in
  min_costs.(0) <- 0;
  let h = H.make 100000 (0, 0) in
  H.push (0, 0) h;
  while not (H.empty_p h) do
    let (u, x) = H.pop h in
    reached_p.(u) <- true;
    if x > min_costs.(u) then ()
    else
      List.iter (fun (v, c) ->
        let x = min_costs.(u) + c in
        if not reached_p.(v) && x < min_costs.(v) then begin
          min_costs.(v) <- x;
          H.push (v, x) h;
        end) g.(u);
  done;
  min_costs

let rec make_pair acc = function
  | [] -> acc
  | v :: c :: tl -> make_pair ((v, c) :: acc) tl
  | _ -> assert false

let make_pair lst = make_pair [] lst

let split_on_char sep s =
  let open String in
  let r = ref [] in
  let j = ref (length s) in
  for i = length s - 1 downto 0 do
    if get s i = sep then begin
      r := sub s (i + 1) (!j - i - 1) :: !r;
      j := i
    end
  done;
  sub s 0 !j :: !r

let () =
  let n = read_int () in
  let g = Array.make n [] in
  for _ = 0 to n - 1 do
    match read_line () |> split_on_char ' ' |> List.map int_of_string with
    | u :: _ :: l -> g.(u) <- make_pair l
    | _ -> assert false
  done;
  dijkstra g n |> Array.iteri (fun i e -> Printf.printf "%d %d\n" i e)

MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Single Source Shortest Path II

For a given weighted graph $G = (V, E)$, find the shortest path from a source to each vertex. For each vertex $u$, print the total weight of edges on the shortest path from vertex $0$ to $u$.

Input

In the first line, an integer $n$ denoting the number of vertices in $G$ is given. In the following $n$ lines, adjacency lists for each vertex $u$ are respectively given in the following format:

$u$ $k$ $v_1$ $c_1$ $v_2$ $c_2$ ... $v_k$ $c_k$

Vertices in $G$ are named with IDs $0, 1, ..., n-1$. $u$ is ID of the target vertex and $k$ denotes its degree. $v_i (i = 1, 2, ... k)$ denote IDs of vertices adjacent to $u$ and $c_i$ denotes the weight of a directed edge connecting $u$ and $v_i$ (from $u$ to $v_i$).

Output

For each vertex, print its ID and the distance separated by a space character in a line respectively. Print in order of vertex IDs.

Constraints

$1 \leq n \leq 10,000$

$0 \leq c_i \leq 100,000$

$|E| < 500,000$

All vertices are reachable from vertex $0$

Sample Input 1

5
0 3 2 3 3 1 1 2
1 2 0 2 3 4
2 3 0 3 3 1 4 1
3 4 2 1 0 1 1 4 4 3
4 2 2 1 3 3

Sample Output 1

0 0
1 2
2 2
3 1
4 3

Reference

Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.


module MakeBinaryHeap (M : sig type t val compare : t -> t -> int end) = struct

  type t = { node : M.t array; mutable size : int }

  let make n (init : M.t) = { node = Array.make n init; size = 0 }

  let empty_p t = if t.size = 0 then true else false

  let pop t =
    let rec max_heapify i =
      let l = 2*i in
      let r = 2*i + 1 in
      let m = if l <= t.size && M.compare t.node.(l) t.node.(i) > 0 then l else i in
      let m = if r <= t.size && M.compare t.node.(r) t.node.(m) > 0 then r else m in
      if m = i then ()
      else begin
        let tmp = t.node.(i) in
        t.node.(i) <- t.node.(m);
        t.node.(m) <- tmp;
        max_heapify m
      end in
    let ret = t.node.(1) in
    t.node.(1) <- t.node.(t.size);
    t.size <- t.size - 1;
    max_heapify 1;
    ret

  let push x t =
    let parent i = int_of_float (floor (float_of_int i) /. 2.) in
    let rec doit i =
      let p = parent i in
      if i <= 1 || M.compare t.node.(p) t.node.(i) >= 0 then ()
      else begin
        let tmp = t.node.(i) in
        t.node.(i) <- t.node.(p);
        t.node.(p) <- tmp;
        doit p
      end in
    t.size <- t.size + 1;
    t.node.(t.size) <- x;
    doit t.size

end

module H = MakeBinaryHeap(struct type t = (int * int) let compare (_, x) (_, y) = y - x end)

let dijkstra g n =
  let reached_p = Array.make n false in
  let d = Array.make n max_int in
  d.(0) <- 0;
  let h = H.make 50000 (0, 0) in
  H.push (0, 0) h;
  while not (H.empty_p h) do
    let (u, x) = H.pop h in
    reached_p.(u) <- true;
    if x > d.(u) then ()
    else
      List.iter (fun (v, c) ->
        let x = d.(u) + c in
        if not reached_p.(v) && x < d.(v) then begin
          d.(v) <- x;
          H.push (v, x) h;
        end) g.(u)
  done;
  d

let rec make_pair acc = function
  | [] -> acc
  | v :: c :: tl -> make_pair ((v, c) :: acc) tl
  | _ -> assert false

let make_pair lst = make_pair [] lst

let split_on_char sep s =
  let open String in
  let r = ref [] in
  let j = ref (length s) in
  for i = length s - 1 downto 0 do
    if get s i = sep then begin
      r := sub s (i + 1) (!j - i - 1) :: !r;
      j := i
    end
  done;
  sub s 0 !j :: !r

let () =
  let n = read_int () in
  let g = Array.make n [] in
  for _ = 0 to n - 1 do
    match read_line () |> split_on_char ' ' |> List.map int_of_string with
    | u :: _ :: l -> g.(u) <- make_pair l
    | _ -> assert false
  done;
  dijkstra g n |> Array.iteri (fun i e -> Printf.printf "%d %d\n" i e)


let pn = 1000000007

let pow m n =
  let rec doit m n acc =
    if n = 0 then acc
    else if n mod 2 = 0 then doit (m * m) (n / 2) acc
    else doit m (n - 1) (acc * m) in
  doit m n 1

let str_fold_left f init s =
  let n = String.length s in
  let rec doit i acc =
    if i = n then acc
    else doit (i + 1) (f acc s.[i]) in
  doit 0 init

let () =
  let p = read_line () in
  let t = read_line () in
  let n = String.length p in
  let m = String.length t in
  let h = Array.make (n + 1) 0 in
  String.iteri (fun i c -> h.(i+1) <- h.(i)*pn + Char.code c) p;
  let ht = str_fold_left (fun acc c -> acc*pn + Char.code c) 0 t in
  let x = pow pn m in
  for i = m to n do
    if h.(i) - h.(i-m)*x = ht then Printf.printf "%d\n" (i - m);
  done

String Search

Find places where a string P is found within a text T.
Print all indices of T where P found. The indices of T start with 0.

Input

In the first line, a text T is given. In the second line, a string P is given.

Output

Print an index of T where P found in a line. Print the indices in ascending order.

Constraints

1 ≤ length of T ≤ 1000000

1 ≤ length of P ≤ 10000

The input consists of alphabetical characters and digits

Sample Input 1

aabaaa
aa

Sample Output 1

0
3
4

Sample Input 2

xyzz
yz

Sample Output 2

1

Sample Input 3

abc
xyz

Sample Output 3

The output should be empty.


let quick_search s p f =
  let sl = String.length s in
  let pl = String.length p in
  let tbl = Hashtbl.create pl in
  let set_tbl () =
    String.iteri (fun i c -> Hashtbl.replace tbl c (pl - i)) p in
  let jump c =
    try Hashtbl.find tbl c with _ -> pl + 1 in
  let rec loopi i =
    if i > sl - pl then ()
    else
      let rec loopj j =
        if j = pl then begin
            f i;
            loopi (i+1)
          end
        else
          if s.[i+j] = p.[j] then loopj (j+1)
          else
            let i' = i + pl in
            if i' >= sl then loopi i'
            else loopi (jump s.[i'] + i)
      in
      loopj 0
  in
  set_tbl ();
  loopi 0

let () =
  let t = read_line () in
  let p = read_line () in
  let f x = string_of_int x |> print_endline in
  quick_search t p f


let (p1, p2, p3) = (257, 251, 1000000007)

let pow x n =
  let rec doit i acc =
    if i = n then acc
    else doit (i + 1) (acc*x mod p3) in
  doit 0 1

let solve a (h, w) b (r, c) =
  let make_hash v (y, x) =
    let h1 = Array.make_matrix y x 0 in
    let c1 = pow p1 c in
    let rec duduwa i =
      if i < y then begin
        let rec calc_z j acc =
          if j = c then acc
          else calc_z (j + 1) ((acc*p1 + Char.code (v.(i).(j))) mod p3) in
        let rec aux j z =
          if j = x - c then h1.(i).(j) <- z
          else begin
            h1.(i).(j) <- z;
            let new_z = (z*p1 - (Char.code v.(i).(j))*c1 + Char.code v.(i).(j+c)) mod p3 in
            aux (j + 1) (if new_z < 0 then new_z + p3 else new_z)
          end in
        aux 0 (calc_z 0 0);
        duduwa (i + 1)
      end in
    duduwa 0;
    let h2 = Array.make_matrix y x 0 in
    let c2 = pow p2 r in
    let rec doit j =
      if j < x then begin
        let rec calc_z i acc =
          if i = r then acc
          else calc_z (i + 1) ((acc*p2 + h1.(i).(j)) mod p3) in
        let rec aux i z =
          if i = y - r then h2.(i).(j) <- z
          else begin
            h2.(i).(j) <- z;
            let new_z = (z*p2 - h1.(i).(j)*c2 + h1.(i+r).(j)) mod p3 in
            aux (i + 1) (if new_z < 0 then new_z + p3 else new_z)
          end in
        aux 0 (calc_z 0 0);
        doit (j + 1)
      end in
    doit 0;
    h2 in
  let s = make_hash a (h, w) in
  let t = make_hash b (r, c) in
  let rec doit = function
    | (i, _) when i > h - r -> ()
    | (i, j) when j > w - c -> doit (i + 1, 0)
    | (i, j) ->
      if s.(i).(j) = t.(0).(0) then Printf.printf "%d %d\n" i j;
      doit (i, j + 1) in
  doit (0, 0)

let split str delim =
  let open String in
  let rec doit s acc =
    match
      try Some (rindex s delim) with _ -> None
    with
    | None -> s :: acc
    | Some i -> doit (sub s 0 i) (sub s (i + 1) (length s - i - 1) :: acc) in
  doit str []

let str_to_list str =
  let rec doit i acc =
    if i < 0 then acc
    else doit (i - 1) (String.get str i :: acc) in
  doit (String.length str - 1) []

let input_array y x =
  let a = Array.make_matrix y x '\000' in
  let rec doit i =
    if i = y then a
    else begin
      let rec aux j = function
        | [] -> ()
        | c :: cs -> a.(i).(j) <- c; aux (j + 1) cs in
      aux 0 (str_to_list (read_line ()));
      doit (i + 1)
    end in
  doit 0

let () =
  match List.map int_of_string (split (read_line ()) ' ') with
  | [h; w] ->
    begin
      let a = input_array h w in
      match List.map int_of_string (split (read_line ()) ' ') with
      | [r; c] ->
        let b = input_array r c in
        solve a (h, w) b (r, c)
      | _ -> exit 1
    end
  | _ -> exit 1

Pattern Search

Find places where a R × C pattern is found within a H × W region. Print top-left coordinates (i, j) of sub-regions where the pattern found. The top-left and bottom-right coordinates of the region is (0, 0) and (H-1, W-1) respectively.

Input

In the first line, two integers H and W are given. In the following H lines, i-th lines of the region are given.

In the next line, two integers R and C are given. In the following R lines, i-th lines of the pattern are given.

output

For each sub-region found, print a coordinate i and j separated by a space character in a line. Print the coordinates in ascending order of the row numbers (i), or the column numbers (j) in case of a tie.

Constraints

1 ≤ H, W ≤ 1000

1 ≤ R, C ≤ 1000

The input consists of alphabetical characters and digits

Sample Input 1

4 5
00010
00101
00010
00100
3 2
10
01
10

Sample Output 1

0 3
1 2


let (p1, p2, p3) = (257, 251, 1000000007)

let pow x n =
  let rec doit i acc =
    if i = n then acc
    else doit (i + 1) (acc*x mod p3) in
  doit 0 1

let solve a (h, w) b (r, c) =
  let make_hash v (y, x) =
    let h1 = Array.make_matrix y x 0 in
    let c1 = pow p1 c in
    let rec duduwa i =
      if i < y then begin
        let rec calc_z j acc =
          if j = c then acc
          else calc_z (j + 1) ((acc*p1 + Char.code v.(i).(j)) mod p3) in
        let rec aux j z =
          if j = x - c then h1.(i).(j) <- z
          else begin
            h1.(i).(j) <- z;
            let new_z = (z*p1 - (Char.code v.(i).(j))*c1 + Char.code v.(i).(j+c)) mod p3 in
            aux (j + 1) (if new_z < 0 then new_z + p3 else new_z)
          end in
        aux 0 (calc_z 0 0);
        duduwa (i + 1)
      end in
    duduwa 0;
    let h2 = Array.make_matrix y x 0 in
    let c2 = pow p2 r in
    let rec doit j =
      if j < x then begin
        let rec calc_z i acc =
          if i = r then acc
          else calc_z (i + 1) ((acc*p2 + h1.(i).(j)) mod p3) in
        let rec aux i z =
          if i = y - r then h2.(i).(j) <- z
          else begin
            h2.(i).(j) <- z;
            let new_z = (z*p2 - h1.(i).(j)*c2 + h1.(i+r).(j)) mod p3 in
            aux (i + 1) (if new_z < 0 then new_z + p3 else new_z)
          end in
        aux 0 (calc_z 0 0);
        doit (j + 1)
      end in
    doit 0;
    h2 in
  let s = make_hash a (h, w) in
  let t = make_hash b (r, c) in
  let rec doit = function
    | (i, _) when i > h - r -> ()
    | (i, j) when j > w - c -> doit (i + 1, 0)
    | (i, j) ->
      if s.(i).(j) = t.(0).(0) then Printf.printf "%d %d\n" i j;
      doit (i, j + 1) in
  doit (0, 0)

let input_array y x =
  let a = Array.make_matrix y x '\000' in
  let rec doit = function
    | (i, _) when i = y -> a
    | (i, j) when j = x -> doit (i + 1, 0)
    | (i, j) ->
      a.(i).(j) <- Scanf.scanf "%c " (fun c -> c);
      doit (i, j + 1) in
  doit (0, 0)

let () =
  let (h, w) = Scanf.scanf "%d %d\n" (fun h w -> (h, w)) in
  let a = input_array h w in
  let (r, c) = Scanf.scanf "%d %d\n" (fun r c -> (r, c)) in
  let b = input_array r c in
  if h >= r && w >= c then solve a (h, w) b (r, c)


open Scanf
open Printf

let id x = x
let tuple x y = (x, y)

let calc_rh a h w r c =
  let bh = 10007 in
  let bv = 999983 in
  let rec pow x n =
    if n = 0 then 1
    else if n mod 2 = 0 then let y = pow x (n / 2) in y * y
    else x * pow x (n-1) in
  let rh a b i j =
    let rec iter r k =
      if k = j then r
      else iter (r * b + a.(k)) (k+1) in
    iter 0 i
  in
  let bh' = pow bh c in
  let ta = Array.make_matrix h (w - c + 1) 0 in
  let rec set_ta i j =
    if i = h then ()
    else if j = w - c + 1 then set_ta (i+1) 0
    else begin
        if j = 0 then ta.(i).(j) <- rh a.(i) bh 0 c
        else ta.(i).(j) <- ta.(i).(j-1) * bh + a.(i).(j+c-1) - a.(i).(j-1) * bh';
        set_ta i (j+1)
      end
  in
  let bv' = pow bv r in
  let rht = Array.make_matrix (h - r + 1) (w - c + 1) 0 in
  let rec set_rht i j =
    if j = w - c + 1 then ()
    else if i = h - r + 1 then set_rht 0 (j+1)
    else begin
        if i = 0 then rht.(i).(j) <- rh (Array.init r (fun k -> ta.(k).(j))) bv 0 r
        else rht.(i).(j) <- rht.(i-1).(j) * bv + ta.(i+r-1).(j) - ta.(i-1).(j) * bv';
        set_rht (i+1) j
      end
  in
  set_ta 0 0;
  set_rht 0 0;
  rht

let () =
  let h, w = scanf "%d %d " tuple in
  let fld = Array.init h (fun _ ->
                          let s = scanf "%s " id in
                          Array.init w (fun i ->
                                        Char.code s.[i]
                                     )
                         ) in
  let r, c = scanf "%d %d " tuple in
  let ptn = Array.init r (fun _ ->
                          let s = scanf "%s " id in
                          Array.init c (fun i ->
                                        Char.code s.[i]
                                       )
                         ) in
  let ft = calc_rh fld h w r c in
  let pt = calc_rh ptn r c r c in
  let rec loop i j =
    if i = h - r + 1 then ()
    else if j = w - c + 1 then loop (i+1) 0
    else begin
        if ft.(i).(j) = pt.(0).(0) then printf "%d %d\n" i j;
        loop i (j+1)
      end
  in
  loop 0 0


let pn = 1000000007

let make_suffix_array t n =
  let ord = Array.make (n + 1) (-1) in
  String.iteri (fun i e -> ord.(i) <- Char.code e) t;
  let sa = Array.init (n + 1) (fun i -> i) in
  let rec doit k =
    if k > n then sa
    else begin
      let cmp a b =
        if ord.(a) <> ord.(b) then ord.(a) - ord.(b)
        else (if a + k <= n then ord.(a+k) else 0) - (if b + k <= n then ord.(b+k) else 0) in
      Array.sort cmp sa;
      let tmp = Array.make (n + 1) 0 in
      let rec aux i =
        if i <= n then begin
          tmp.(sa.(i)) <- tmp.(sa.(i-1)) + (if cmp sa.(i-1) sa.(i) < 0 then 1 else 0);
          aux (i + 1)
        end in
      aux 1;
      Array.iteri (fun i e -> ord.(i) <- e) tmp;
      doit (k * 2)
    end in
  doit 1

let pow x n =
  let rec doit i acc =
    if i = n then acc
    else doit (i + 1) (acc*x) in
  doit 0 1

let str_fold_left f init s =
  let n = String.length s in
  let rec doit i acc =
    if i = n then acc
    else doit (i + 1) (f acc s.[i]) in
  doit 0 init

let contain_p x y =
  let n = String.length x in
  let m = String.length y in
  let h = Array.make (n + 1) 0 in
  String.iteri (fun i c -> h.(i+1) <- h.(i)*pn + Char.code c) x;
  let ht = str_fold_left (fun acc c -> acc*pn + Char.code c) 0 y in
  let x = pow pn m in
  let rec doit i =
    if i > n then false
    else if h.(i) - h.(i-m)*x = ht then true
    else doit (i + 1) in
  doit m

let () =
  let t = read_line () in
  let n = String.length t in
  let sa = make_suffix_array t n in
  let q = read_int () in
  let rec doit i =
    if i < q then begin
      let p = read_line () in
      let rec aux l r =
        if l >= r then r
        else begin
          let m = (l + r) / 2 in
          if compare (String.sub t sa.(m) (n - sa.(m))) p < 0 then aux (m + 1) r
          else aux l m
        end in
      let r = aux 0 n in
      Printf.printf "%d\n" (if contain_p (String.sub t sa.(r) (if n - sa.(r) - (String.length p) >= 0 then String.length p else n - sa.(r))) p then 1 else 0);
      doit (i + 1)
    end in
  doit 0

String Search

Determine whether a text T includes a pattern P. Your program should answer for given queries consisting of P_i.

Input

In the first line, a text T is given. In the second line, an integer Q denoting the number of queries is given. In the following Q lines, the patterns P_i are given respectively.

Output

For each question, print 1 if the text includes P_i, or print 0 otherwise.

Constraints

1 ≤ length of T ≤ 1000000

1 ≤ length of P_i ≤ 1000

1 ≤ Q ≤ 10000

The input consists of alphabetical characters and digits

Sample Input 1

aabaaa
4
aa
ba
bb
xyz

Sample Output 1

1
1
0
0


exception Not_equal of int

let rank = Array.make 1000000 0
let tmp = Array.make 1000000 0

let cmp_sa rank a b n k =
  if rank.(a) <> rank.(b) then compare rank.(a) rank.(b)
  else
    compare
      (if a + k <= n then rank.(a+k) else (-1))
      (if b + k <= n then rank.(b+k) else (-1))

let construct_sa t n =
  let sa = Array.make (n + 1) 0 in
  for i = 0 to n - 1 do
    sa.(i) <- i;
    rank.(i) <- Char.code t.[i];
  done;
  sa.(n) <- n;
  rank.(n) <- (-1);
  let k = ref 1 in
  while !k <= n do
    Array.sort (fun a b -> cmp_sa rank a b n !k) sa;
    tmp.(sa.(0)) <- 0;
    for i = 1 to n do
      tmp.(sa.(i)) <-
        tmp.(sa.(i-1)) + (if cmp_sa rank sa.(i-1) sa.(i) n !k = (-1) then 1 else 0);
    done;
    for i = 0 to n do rank.(i) <- tmp.(i) done;
    k := !k * 2;
  done;
  sa

let range_cmp t n offset p k =
  let m = n - offset in
  let m = if m < k then m else k in
  try
    for i = 0 to m - 1 do
      if t.[i+offset] <> p.[i] then
        raise (Not_equal (compare t.[i+offset] p.[i]));
    done;
    if m = k then 0
    else (-1)
  with Not_equal i -> i

let () =
  let t = read_line () in
  let n = String.length t in
  let sa = construct_sa t n in
  let q = read_int () in
  for _ = 0 to q - 1 do
    let p = read_line () in
    let k = String.length p in
    let l = ref 0 in
    let r = ref (n + 1) in
    while !l + 1 < !r do
      let m = (!l + !r) / 2 in
      let ret = range_cmp t n sa.(m) p k in
      if ret <= 0 then l := m
      else r := m;
    done;
    Printf.printf "%d\n" (if range_cmp t n sa.(!l) p k = 0 then 1 else 0);
  done


exception Not_equal of int

let cmp_sa rank a b n k =
  if rank.(a) <> rank.(b) then compare rank.(a) rank.(b)
  else
    compare
      (if a + k <= n then rank.(a+k) else (-1))
      (if b + k <= n then rank.(b+k) else (-1))

let construct_sa t n =
  let sa = Array.make (n + 1) 0 in
  let rank = Array.make (n + 1) 0 in
  let tmp = Array.make (n + 1) 0 in
  for i = 0 to n - 1 do
    sa.(i) <- i;
    rank.(i) <- Char.code t.[i];
  done;
  sa.(n) <- n;
  rank.(n) <- (-1);
  let k = ref 1 in
  while !k <= n do
    Array.sort (fun a b -> cmp_sa rank a b n !k) sa;
    tmp.(sa.(0)) <- 0;
    for i = 1 to n do
      tmp.(sa.(i)) <-
        tmp.(sa.(i-1)) + (if cmp_sa rank sa.(i-1) sa.(i) n !k = (-1) then 1 else 0);
    done;
    for i = 0 to n do rank.(i) <- tmp.(i) done;
    k := !k * 2;
  done;
  sa

let range_cmp t n offset p k =
  let m = n - offset in
  let m = if m < k then m else k in
  try
    for i = 0 to m - 1 do
      if t.[i+offset] <> p.[i] then
        raise (Not_equal (compare t.[i+offset] p.[i]));
    done;
    if m = k then 0
    else (-1)
  with Not_equal i -> i

let () =
  let t = read_line () in
  let n = String.length t in
  let sa = construct_sa t n in
  let q = read_int () in
  for _ = 0 to q - 1 do
    let p = read_line () in
    let k = String.length p in
    let l = ref 0 in
    let r = ref (n + 1) in
    while !l + 1 < !r do
      let m = (!l + !r) / 2 in
      let ret = range_cmp t n sa.(m) p k in
      if ret <= 0 then l := m
      else r := m;
    done;
    Printf.printf "%d\n" (if range_cmp t n sa.(!l) p k = 0 then 1 else 0);
  done


let is_prime n = match n with
    2|3|5|7 -> true
    | n when n mod 2 = 0 -> false
    | n ->
       let rec loop i =
         if i*i > n then true
         else if n mod i = 0 then false
         else loop (i+2);
       in loop 3

let () =
  let n = read_int () in
  let rec read ct = function
      0 -> ct
    | i ->
       let m = read_int () in
       read (if is_prime m then ct+1 else ct) (i-1)
  in
  Printf.printf "%d\n" (read 0 n)

Prime Numbers

A prime number is a natural number which has exactly two distinct natural number divisors: 1 and itself. For example, the first four prime numbers are: 2, 3, 5 and 7.

Write a program which reads a list of N integers and prints the number of prime numbers in the list.

Input

The first line contains an integer N, the number of elements in the list.

N numbers are given in the following lines.

Output

Print the number of prime numbers in the given list.

Constraints

1 ≤ N ≤ 10000

2 ≤ an element of the list ≤ 108

Sample Input 1

5
2
3
4
5
6

Sample Output 1

3

Sample Input 2

11
7
8
9
10
11
12
13
14
15
16
17

Sample Output 2

4


let is_prime n =
  if n = 2 || n = 3 || n = 5 then true
  else if n mod 2 = 0 || n mod 3 = 0 || n mod 5 = 0 then false
  else
    let rec loop i =
      if i*i > n then true
      else if n mod i = 0 then false
      else if n mod (i+2) = 0 then false
      else loop (i+6);
    in loop 5

let () =
  let n = read_int () in
  let rec read ct = function
      0 -> ct
    | i ->
       let m = read_int () in
       read (if is_prime m then ct+1 else ct) (i-1)
  in
  Printf.printf "%d\n" (read 0 n)


let () =
  let n = read_int () in
  let rec doit i m ans =
    if i >= n then ans
    else let r = read_int () in let x = r - m in doit (i + 1) (if m < r then m else r) (if x > ans then x else ans)
  in
  Printf.printf "%d\n" (doit 1 (read_int ()) min_int)

MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Maximum Profit

You can obtain profits from foreign exchange margin transactions. For example, if you buy 1000 dollar at a rate of 100 yen per dollar, and sell them at a rate of 108 yen per dollar, you can obtain (108 - 100) × 1000 = 8000 yen.

Write a program which reads values of a currency $R_t$ at a certain time $t$ ($t = 0, 1, 2, ... n-1$), and reports the maximum value of $R_j - R_i$ where $j > i$ .

Input

The first line contains an integer $n$. In the following $n$ lines, $R_t$ ($t = 0, 1, 2, ... n-1$) are given in order.

Output

Print the maximum value in a line.

Constraints

$2 \leq n \leq 200,000$

$1 \leq R_t \leq 10^9$

Sample Input 1

6
5
3
1
3
4
3

Sample Output 1

3

Sample Input 2

3
4
3
2

Sample Output 2

-1


let split str delim =
  let rec doit s acc =
    match
      try Some (String.rindex s delim) with _ -> None
    with
    | None -> s :: acc
    | Some i ->
        let s1 = String.sub s 0 i in
        let s2 = String.sub s (i + 1) (String.length s - String.length s1 - 1) in
        doit s1 (s2 :: acc)
  in
  doit str []

let () =
  let open Queue in
  let (que : (string * int) Queue.t) = create () in
  match List.map int_of_string (split (read_line ()) ' ') with
  | [n; q] -> begin
      let rec read i =
        if i < n then begin
          match split (read_line ()) ' ' with
          | [s; t] -> (add (s, int_of_string t) que; read (i + 1))
          | _ -> exit 1
        end
      in
      read 0;
      let rec doit cnt =
        if not (is_empty que) then begin
          let s, t = take que in
          let rest = t - q in
          if rest <= 0 then (let x = cnt + t in print_string s; print_char ' '; print_int x; print_char '\n'; doit x)
          else (add (s, rest) que; doit (cnt + q))
        end
      in
      doit 0
    end
  | _ -> exit 1

There are n processes in a queue. Each process has namei and timei. The round-robin scheduling handles the processes in order. A round-robin scheduler gives each process a quantum (a time slot) and interrupts the process if it is not completed by then. The process is resumed and moved to the end of the queue, then the scheduler handles the next process in the queue.

For example, we have the following queue with the quantum of 100ms.

A(150) - B(80) - C(200) - D(200)

First, process A is handled for 100ms, then the process is moved to the end of the queue with the remaining time (50ms).

B(80) - C(200) - D(200) - A(50)

Next, process B is handled for 80ms. The process is completed with the time stamp of 180ms and removed from the queue.

C(200) - D(200) - A(50)

Your task is to write a program which simulates the round-robin scheduling.

Input

n q

name1 time1

name2 time2

...

namen timen

In the first line the number of processes n and the quantum q are given separated by a single space.

In the following n lines, names and times for the n processes are given. namei and timei are separated by a single space.

Output

For each process, prints its name and the time the process finished in order.

Constraints

1 ≤ n ≤ 100000

1 ≤ q ≤ 1000

1 ≤ timei ≤ 50000

1 ≤ length of namei ≤ 10

1 ≤ Sum of timei ≤ 1000000

Sample Input 1

5 100
p1 150
p2 80
p3 200
p4 350
p5 20

Sample Output 1

p2 180
p5 400
p1 450
p3 550
p4 800

Notes

Template in C


let () =
  let open Queue in
  let (n:int),(quantum:int) = Scanf.scanf "%d %d\n" (fun a b -> a,b) in
  let (q:(string * int) t) = create () in
  try
    while true do
      add (Scanf.scanf "%s %d\n" (fun a b -> a,b)) q
    done;
  with _ ->
    let (sum:int ref) = ref 0 in
    try
      while true do
        let (p:string),(t:int) = take q in
        if t <= quantum then (sum := !sum+t; Printf.printf "%s %d\n" p !sum)
        else (add (p,t-quantum) q; sum := !sum+quantum)
      done;
    with _ -> ()


let () =
  let open Queue in
  let (n:int),(quantum:int) = Scanf.scanf "%d %d\n" (fun a b -> a,b) in
  let (q:(string * int) t) = create () in
  for i=1 to n do
    add (Scanf.scanf "%s %d\n" (fun a b -> a,b)) q
  done;
  let (sum:int ref) = ref 0 in
  while not (is_empty q) do
    let (p:string),(t:int) = take q in
    if t <= quantum then begin sum := !sum+t; Printf.printf "%s %d\n" p !sum end
    else begin add (p,t-quantum) q; sum := !sum+quantum end
  done


module Queue' = struct
  type 'a t = {
    mutable front : int;
    mutable mask  : int;
    mutable index : int;
    mutable length : int;
    mutable elems : 'a option array
  }

  let capacity t = t.mask + 1

  let is_empty t = t.length = 0

  let create ?(capacity=1) () =
    { front = 0;
      mask  = capacity - 1;
      index = 0;
      length = 0;
      elems = Array.make capacity None}

  let enq t a =
    let elems = t.elems in
    elems.(t.index) <- (Some a);
    t.length <- t.length + 1;
    t.index <- (t.index + 1) mod (capacity t)

  let deq t =
    let elems = t.elems in
    let front = t.front in
    let res = elems.(front) in
    t.front <- (t.front + 1) mod (capacity t);
    t.length <- t.length - 1;
    res

  let get_elems t = t.elems
  let get_index t = t.index
end

let () =
  let open Queue' in
  let (n:int),(quantum:int) = Scanf.scanf "%d %d\n" (fun a b -> a,b) in
  let (q:(string * int) t) = create ~capacity:n () in
  for i=1 to n do
    enq q (Scanf.scanf "%s %d\n" (fun a b -> a,b));
  done;
  let (sum:int ref) = ref 0 in
  while not (is_empty q) do
    let (p:string),(t:int) = match deq q with None -> "",0 | Some x -> x in
    if t <= quantum then (sum := !sum+t; Printf.printf "%s %d\n" p !sum)
    else (enq q (p,t-quantum); sum := !sum+quantum)
  done


let () =
  let open Queue in
  let (n:int),(quantum:int) = Scanf.scanf "%d %d\n" (fun a b -> a,b) in
  let (q:(string * int) t) = create () in
  for i=1 to n do
    add (Scanf.scanf "%s %d\n" (fun a b -> a,b)) q
  done;
  let (sum:int ref) = ref 0 in
  while not (is_empty q) do
    match take q with
      p,t when t <= quantum ->
      sum := !sum + t;
      Printf.printf "%s %d\n" p !sum
    | p,t ->
      add (p,t-quantum) q;
      sum := !sum+quantum
  done


module DoublyLinkedList = struct
  type t = {
    mutable data : int;
    mutable next : t;
    mutable prev : t;
  }

  let make () =
    let rec head = { data = 0; next = head; prev = head } in
    head

  let insert data head =
    let x = { data = data; next = head.next; prev = head } in
    head.next.prev <- x;
    head.next <- x

  let delete x =
    x.next.prev <- x.prev;
    x.prev.next <- x.next

  let delete_first head = delete head.next

  let delete_last head = delete head.prev

  let delete_node data head =
    let rec doit ite =
      if ite == head || ite.data = data then ite
      else doit ite.next
    in
    delete (doit head.next)

  let iteri head ~f =
    let rec doit i ite =
      if ite == head then ()
      else (f i ite.data; doit (i + 1) ite.next)
    in
    doit 0 head.next
end

module L = DoublyLinkedList

let split str delim =
  let rec doit s acc =
    match
      try Some (String.index s delim)
      with _ -> None
    with
    | None -> List.rev (s :: acc)
    | Some i ->
        let s1 = String.sub s 0 i in
        let s2 = String.sub s (i + 1) (String.length s - String.length s1 - 1) in
        doit s2 (s1 :: acc)
  in
  doit str []

let _ =
  let n = read_int () in
  let head = L.make () in
  let rec read i =
    if i >= n then ()
    else begin
      match split (read_line ()) ' ' with
      | "insert" :: n :: _ -> (L.insert (int_of_string n) head; read (i + 1))
      | "delete" :: n :: _ -> (L.delete_node (int_of_string n) head; read (i + 1))
      | "deleteFirst" :: _ -> (L.delete_first head; read (i + 1))
      | "deleteLast" :: _ -> (L.delete_last head; read (i + 1))
      | _ -> exit 1
    end
  in
  read 0;
  L.iteri head ~f:(fun i n -> Printf.printf (if i = 0 then "%d" else " %d") n);
  print_newline ()

Doubly Linked List

Your task is to implement a double linked list.

Write a program which performs the following operations:

insert x: insert an element with key x into the front of the list.

delete x: delete the first element which has the key of x from the list. If there is not such element, you need not do anything.

deleteFirst: delete the first element from the list.

deleteLast: delete the last element from the list.

Input

The input is given in the following format:

n

command1

command2

...

commandn

In the first line, the number of operations n is given. In the following n lines, the above mentioned operations are given in the following format:

insert x

delete x

deleteFirst

deleteLast

Output

Print all the element (key) in the list after the given operations. Two consequtive keys should be separated by a single space.

Constraints

The number of operations ≤ 2,000,000

The number of delete operations ≤ 20

0 ≤ value of a key ≤ 109

The number of elements in the list does not exceed 106

For a delete, deleteFirst or deleteLast operation, there is at least one element in the list.

Sample Input 1

7
insert 5
insert 2
insert 3
insert 1
delete 3
insert 6
delete 5

Sample Output 1

6 1 2

Sample Input 2

9
insert 5
insert 2
insert 3
insert 1
delete 3
insert 6
delete 5
deleteFirst
deleteLast

Sample Output 2

1


module DoublyLinkedList = struct
  type t = {
    mutable data : int;
    mutable next : t;
    mutable prev : t;
  }

  let make () =
    let rec head = { data = 0; next = head; prev = head } in
    head

  let insert data head =
    let x = { data = data; next = head.next; prev = head } in
    head.next.prev <- x;
    head.next <- x

  let delete x =
    x.next.prev <- x.prev;
    x.prev.next <- x.next

  let delete_first head = delete head.next

  let delete_last head = delete head.prev

  let delete_node data head =
    let rec doit ite =
      if ite == head then None
      else if ite.data = data then Some ite
      else doit ite.next
    in
    match doit head.next with
    | None -> ()
    | Some ite -> delete ite

  let iteri head ~f =
    let rec doit i ite =
      if ite == head then ()
      else (f i ite.data; doit (i + 1) ite.next)
    in
    doit 0 head.next
end

module L = DoublyLinkedList

let () =
  let n = read_int () in
  let head = L.make () in
  let rec read i =
    if i >= n then ()
    else begin
      match Str.split (Str.regexp " ") (read_line ()) with
      | ["insert"; n] -> (L.insert (int_of_string n) head; read (i + 1))
      | ["delete"; n] -> (L.delete_node (int_of_string n) head; read (i + 1))
      | ["deleteFirst"] -> (L.delete_first head; read (i + 1))
      | ["deleteLast"] -> (L.delete_last head; read (i + 1))
      | _ -> exit 1
    end
  in
  read 0;
  L.iteri head ~f:(fun i n -> Printf.printf (if i = 0 then "%d" else " %d") n);
  print_newline ()


module DoublyLinkedList = struct
  type t = {
    mutable data : int;
    mutable next : t;
    mutable prev : t;
  }

  let make () =
    let rec head = { data = 0; next = head; prev = head } in
    head

  let insert data head =
    let x = { data = data; next = head.next; prev = head } in
    head.next.prev <- x;
    head.next <- x

  let delete x =
    x.next.prev <- x.prev;
    x.prev.next <- x.next

  let delete_first head = delete head.next

  let delete_last head = delete head.prev

  let delete_node data head =
    let rec doit ite =
      if ite == head then None
      else if ite.data = data then Some ite
      else doit ite.next in
    match doit head.next with
    | None -> ()
    | Some ite -> delete ite

  let iteri f head =
    let rec doit i ite =
      if ite == head then ()
      else begin
        f i ite.data;
        doit (i + 1) ite.next
      end in
    doit 0 head.next
end

module L = DoublyLinkedList

let split_on_char sep s =
  let open String in
  let r = ref [] in
  let j = ref (length s) in
  for i = length s - 1 downto 0 do
    if get s i = sep then begin
      r := sub s (i + 1) (!j - i - 1) :: !r;
      j := i
    end
  done;
  sub s 0 !j :: !r

let () =
  let n = read_int () in
  let head = L.make () in
  for _ = 0 to n - 1 do
    match split_on_char ' ' (read_line ()) with
    | ["insert"; n] -> L.insert (int_of_string n) head
    | ["delete"; n] -> L.delete_node (int_of_string n) head
    | ["deleteFirst"] -> L.delete_first head
    | _ -> L.delete_last head
  done;
  L.iteri (fun i n -> if i <> 0 then print_string " "; print_int n) head;
  print_newline ()


module DoublyLinkedList = struct

  type t = {
    mutable data : int;
    mutable next : t;
    mutable prev : t;
  }

  let make () =
    let rec head = { data = 0; next = head; prev = head } in
    head

  let insert data head =
    let x = { data = data; next = head.next; prev = head } in
    head.next.prev <- x;
    head.next <- x

  let delete x =
    x.next.prev <- x.prev;
    x.prev.next <- x.next

  let delete_first head = delete head.next

  let delete_last head = delete head.prev

  let delete_node data head =
    let rec doit ite =
      if ite == head then None
      else if ite.data = data then Some ite
      else doit ite.next in
    match doit head.next with
    | None -> ()
    | Some ite -> delete ite

  let iteri f head =
    let rec doit i ite =
      if ite == head then ()
      else begin
        f i ite.data;
        doit (i + 1) ite.next
      end in
    doit 0 head.next

end

module L = DoublyLinkedList

let split_on_char sep s =
  let open String in
  let r = ref [] in
  let j = ref (length s) in
  for i = length s - 1 downto 0 do
    if get s i = sep then begin
      r := sub s (i + 1) (!j - i - 1) :: !r;
      j := i
    end
  done;
  sub s 0 !j :: !r

let () =
  let n = read_int () in
  let head = L.make () in
  for _ = 0 to n - 1 do
    match split_on_char ' ' (read_line ()) with
    | ["insert"; n] -> L.insert (int_of_string n) head
    | ["delete"; n] -> L.delete_node (int_of_string n) head
    | ["deleteFirst"] -> L.delete_first head
    | _ -> L.delete_last head
  done;
  L.iteri (fun i n -> if i <> 0 then print_string " "; print_int n) head;
  print_newline ()


let analysis (area:string) =
  let len = String.length area in
  let stack = Stack.create () in
  let rec loop acc = function
      i when i = len -> acc
    | i ->
      match area.[i] with
      | '\\' -> Stack.push i stack; loop acc (i+1)
      | '/' -> loop
                 (match Stack.length stack with
                    0 -> acc
                  | _ -> let j = Stack.pop stack in
                    (((j,i),i-j)::acc))
                 (i+1)
      | _ -> loop acc (i+1)
  in loop [] 0

let summarize lst =
  let rec loop acc cnt sum = function
      []  -> acc,cnt,sum
    | [x] -> x::acc,cnt+1,sum+(snd x)
    | ((s1,e1),v1)::((s2,e2),v2)::r when s1 < s2 && e1 > e2 ->
      loop acc cnt sum (((s1,e1), v1+v2)::r)
    | (_,v) as a::(b::r as rest) -> loop (a::acc) (cnt+1) (sum+v) rest
  in loop [] 0 0 lst

let () =
  let line = read_line () in
  let part,cnt,sum = analysis line |> summarize in
  Printf.printf "%d\n%d" sum cnt;
  List.iter (fun (_,v) -> Printf.printf " %d" v) part;
  print_newline ()

MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Areas on the Cross-Section Diagram

Your task is to simulate a flood damage.

For a given cross-section diagram, reports areas of flooded sections.

Assume that rain is falling endlessly in the region and the water overflowing from the region is falling in the sea at the both sides.
For example, for the above cross-section diagram, the rain will create floods which have areas of 4, 2, 1, 19 and 9 respectively.

Input

A string, which represents slopes and flatlands by '/', '\' and '_' respectively, is given in a line. For example, the region of the above example is given by a string "\\///\_/\/\\\\/_/\\///__\\\_\\/_\/_/\".

output

Report the areas of floods in the following format:

$A$

$k$ $L_1$ $L_2$ ... $L_k$

In the first line, print the total area $A$ of created floods.

In the second line, print the number of floods $k$ and areas $L_i (i = 1, 2, ..., k)$ for each flood from the left side of the cross-section diagram. Print a space character before $L_i$.

Constraints

$1 \leq$ length of the string $\leq 20,000$

Sample Input 1

\\//

Sample Output 1

4
1 4

Sample Input 2

\\///\_/\/\\\\/_/\\///__\\\_\\/_\/_/\

Sample Output 2

35
5 4 2 1 19 9


let to_array s =
  Str.split (Str.regexp_string " ") s
  |> List.map int_of_string
  |> Array.of_list;;

let binary_search l value index =
  let rec loop left right =
    let mid = (left+right)/2 in
    if mid = left then
      if l.(left) = value then (true, left)
      else if l.(right) = value then (true, right)
      else (false, left)
    else
      let (left_new, right_new) =
        if l.(mid) > value then (left,mid-1)
        else if l.(mid) < value then (mid+1, right)
        else (-1,-1)
      in
      if left_new = -1 && right_new = -1 then (true, mid)
      else loop left_new right_new
  in loop index ((Array.length l)-1)
;;

let _ = read_int () and
    s = read_line () |> to_array and
    _ = read_int () and
    t = read_line () |> to_array  in
    Array.sort compare t;
    let f x y =
      let (count, index) = x in
      let (found, index_new) = binary_search s y index in
      if found then (count+1, index_new) else (count, index_new)
    in
    let (count, _) = Array.fold_left f (0,0) t in
    Printf.printf "%d\n" count
;;

Search II

You are given a sequence of n integers S and a sequence of different q integers T. Write a program which outputs C, the number of integers in T which are also in the set S.

Input

In the first line n is given. In the second line, n integers are given. In the third line q is given. Then, in the fourth line, q integers are given.

Output

Print C in a line.

Constraints

Elements in S is sorted in ascending order

n ≤ 100000

q ≤ 50000

0 ≤ an element in S ≤ 109

0 ≤ an element in T ≤ 109

Sample Input 1

5
1 2 3 4 5
3
3 4 1

Sample Output 1

3

Sample Input 2

3
1 2 3
1
5

Sample Output 2

0

Sample Input 3

5
1 1 2 2 3
2
1 2

Sample Output 3

2

Notes


let bin_search x (a : int array) =
  let rec doit l r =
    if l >= r then false
    else
      let m = (l + r) / 2 in
      if x = a.(m) then true
      else if x < a.(m) then doit l m
      else doit (m + 1) r in
  doit 0 (Array.length a)

let split_on_char sep s =
  let open String in
  let r = ref [] in
  let j = ref (length s) in
  for i = length s - 1 downto 0 do
    if get s i = sep then begin
      r := sub s (i + 1) (!j - i - 1) :: !r;
      j := i
    end
  done;
  sub s 0 !j :: !r

let () =
  let read_seq () = List.map int_of_string (split_on_char ' ' (read_line ())) in
  let _ = read_int () in
  let s = Array.of_list (read_seq ()) in
  let _ = read_int () in
  let t = read_seq () in
  Printf.printf "%d\n" (List.fold_left (fun acc e -> acc + (if bin_search e s then 1 else 0)) 0 t)


let () =
  let (n, k) = Scanf.scanf "%d %d\n" (fun n k -> (n, k)) in
  let a = Array.init n (fun _ -> Scanf.scanf "%d\n" (fun i -> i)) in
  let check p =
    let rec doit i j s =
      if i = n then n
      else if j >= k then i
      else
        let x = s + a.(i) in
        if x > p then doit i (j + 1) 0
        else doit (i + 1) j x
    in
    doit 0 0 0
  in
  let rec bin_search l r =
    if r < l then l
    else
      let m = (l + r) / 2 in
      if check m >= n then bin_search l (m - 1)
      else bin_search (m + 1) r
  in
  Printf.printf "%d\n" (bin_search 0 (100000 * 10000))

MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

You are given $n$ packages of $w_i$ kg from a belt conveyor in order ($i = 0, 1, ... n-1$). You should load all packages onto $k$ trucks which have the common maximum load $P$. Each truck can load consecutive packages (more than or equals to zero) from the belt conveyor unless the total weights of the packages in the sequence does not exceed the maximum load $P$.

Write a program which reads $n$, $k$ and $w_i$, and reports the minimum value of the maximum load $P$ to load all packages from the belt conveyor.

Input

In the first line, two integers $n$ and $k$ are given separated by a space character. In the following $n$ lines, $w_i$ are given respectively.

Output

Print the minimum value of $P$ in a line.

Constraints

$1 \leq n \leq 100,000$

$1 \leq k \leq 100,000$

$1 \leq w_i \leq 10,000$

Sample Input 1

5 3
8
1
7
3
9

Sample Output 1

10

If the first truck loads two packages of $\{8, 1\}$, the second truck loads two packages of $\{7, 3\}$ and the third truck loads a package of $\{9\}$, then the minimum value of the maximum load $P$ shall be 10.

Sample Input 2

4 2
1
2
2
6

Sample Output 2

6

If the first truck loads three packages of $\{1, 2, 2\}$ and the second truck loads a package of $\{6\}$, then the minimum value of the maximum load $P$ shall be 6.


let () =
  let (n, k) = Scanf.scanf "%d %d " (fun n k -> (n, k)) in
  let a = Array.init n (fun _ -> Scanf.scanf "%d " (fun i -> i)) in
  let check p =
    let rec doit i j s =
      if i = n then n
      else if j >= k then i
      else
        let x = s + a.(i) in
        if x > p then doit i (j + 1) 0
        else doit (i + 1) j x
    in
    doit 0 0 0
  in
  let rec bin_search l r =
    if r < l then l
    else
      let m = (l + r) / 2 in
      if check m >= n then bin_search l (m - 1)
      else bin_search (m + 1) r
  in
  Printf.printf "%d\n" (bin_search 0 (100000 * 10000))


let split str delim =
  let open String in
  let rec doit s acc =
    match
      try Some (rindex s delim) with _ -> None
    with
    | None -> s :: acc
    | Some i -> doit (sub s 0 i) (sub s (i + 1) (length s - i - 1) :: acc)
  in doit str []

let () =
  match List.map int_of_string (split (read_line ()) ' ') with
  | [n; k] -> begin
      let a = Array.init n (fun _ -> read_int ()) in
      let rec check p =
        let rec doit i j s =
          if i = n then n
          else if j >= k then i
          else
            let x = s + a.(i) in
            if x > p then doit i (j + 1) 0
            else doit (i + 1) j x
        in doit 0 0 0
      and bin_search l r =
        if r < l then l
        else
          let m = (l + r) / 2 in
          if check m >= n then bin_search l (m - 1)
          else bin_search (m + 1) r
      in Printf.printf "%d\n" (bin_search 0 (100000 * 10000))
    end
  | _ -> exit 1


let () =
  let (n,k) = Scanf.scanf "%d %d\n" (fun x y->(x,y)) in
  let a = Array.init n (fun _ -> Scanf.scanf "%d\n" (fun x->x)) in
  let l = Array.fold_left (fun x y -> max x y) 0 a and
      r = 100000*100000 in
  let rec load ((i,j,s,p):int*int*int*int):bool =
    if i=n then true
    else if j=k then false
    else
      if s+a.(i) <= p then load ((i+1), j, (s+a.(i)), p) else load (i,(j+1),0,p)
  in
  let rec loop (left:int) (right:int):int =
    if left < right then
      let mid = (left+right)/2 in
      if load (0,0,0,mid) then loop left mid
      else loop (mid+1) right
    else right
  in
  Printf.printf "%d\n" (loop l r)
;;


let split str =
  let rec split_inner ct b=
    if String.length str = ct then [(int_of_string b)]
    else
      match str.[ct] with
        ' ' -> (int_of_string b)::split_inner (ct+1) ""
      | c -> split_inner (ct+1) (b^(Char.escaped c))
  in split_inner 0 "";;

let () =
  let (n,k) = match split (read_line ()) with
        [n;k] -> (n,k)
      | _ -> raise Not_found
  in
  let ws = Array.init n (fun _ -> read_int ()) and
       l = 0 and
       r = 100000*100000
  in
  let rec search ((i,j,s,p):int*int*int*int) =
    if i=n || j=k then i
    else
      if s+ws.(i) <= p then
        search ((i+1), j, (s+ws.(i)), p)
      else
        search (i,(j+1),0,p)
  in
  let rec loop (left:int) (right:int) =
    if left < right then
      let mid = (left+right)/2 in
      if search (0,0,0,mid) >= n then loop left mid
      else loop (mid+1) right
    else right
  in
  Printf.printf "%d\n" (loop l r)
;;


open String
let f s=let r=ref[]and j=ref(length s)in for i=length s-1downto 0do if s.[i]=' 'then(r:=sub s(i+1)(!j-i-1)::!r;j:=i)done;sub s 0!j::!r
and g n k a=let rec($)l r=if r<l then l else if h(0,0,0,(l+r)/2)<n then((l+r)/2+1)$r else l$((l+r)/2-1)and h=function(i,j,x,p)->if i=n||j=k then i else if x+a.(i)<=p then h(i+1,j,x+a.(i),p)else h(i,j+1,0,p)in 0$1000000000;;match List.map int_of_string(f(read_line()))with[n;k]->Printf.printf"%d
"(g n k(Array.init n(fun _->read_int())))|_->()


let words str =
  let len = String.length str in
  let buf = Buffer.create 10 in
  let rec loop cont = function
      i when i = len -> cont [Buffer.contents buf |> int_of_string]
    | i ->
      loop
        (match str.[i] with
         | ' ' ->
           let v = Buffer.contents buf |> int_of_string in
           Buffer.clear buf; (fun x -> cont (v::x))
         | c ->
           Buffer.add_char buf c; cont)
        (i+1)
  in loop (fun x -> x) 0

let check n seq =
  let filtered = List.filter (fun x -> x <= n) seq in
  let rec loop l results = match l with
      [] -> if List.mem n results then "yes" else "no"
    | h::t -> List.append results (List.map (fun v -> v+h) results)
              |> loop t
  in
  loop filtered [0]

let () =
  let _ = read_int () in
  let an = read_line () |> words in
  let _ = read_int () in
  let mi = read_line () |> words in
  List.iter (fun x -> check x an |> Printf.printf "%s\n") mi

Exhaustive Search

Write a program which reads a sequence A of n elements and an integer M, and outputs "yes" if you can make M by adding elements in A, otherwise "no". You can use an element only once.

You are given the sequence A and q questions where each question contains Mi.

Input

In the first line n is given. In the second line, n integers are given. In the third line q is given. Then, in the fourth line, q integers (Mi) are given.

Output

For each question Mi, print yes or no.

Constraints

n ≤ 20

q ≤ 200

1 ≤ elements in A ≤ 2000

1 ≤ Mi ≤ 2000

Sample Input 1

5
1 5 7 10 21
8
2 4 17 8 22 21 100 35

Sample Output 1

no
no
yes
yes
yes
yes
no
no

Notes

You can solve this problem by a Burte Force approach. Suppose solve(p, t) is a function which checkes whether you can make t by selecting elements after p-th element (inclusive). Then you can recursively call the following functions:

solve(0, M)

solve(1, M-{sum created from elements before 1st element})

solve(2, M-{sum created from elements before 2nd element})

...

The recursive function has two choices: you selected p-th element and not. So, you can check solve(p+1, t-A[p]) and solve(p+1, t) in solve(p, t) to check the all combinations.

For example, the following figure shows that 8 can be made by A[0] + A[2].


let cnt = ref 0

let merge a l m r =
  let init_ary n p = Array.init (n + 1) (fun i -> if i = n then max_int else a.(p + i)) in
  let ai = init_ary (m - l) l in
  let aj = init_ary (r - m) m in
  let rec doit = function
    | (_, _, k) when k = r -> ()
    | (i, j, k) ->
      incr cnt;
      if ai.(i) <= aj.(j) then begin
        a.(k) <- ai.(i);
        doit (i + 1, j, k + 1)
      end else begin
        a.(k) <- aj.(j);
        doit (i, j + 1, k + 1)
      end in
  doit (0, 0, l)

let rec merge_sort a l r =
  if (l + 1) < r then begin
    let m = (l + r) / 2 in
    merge_sort a l m;
    merge_sort a m r;
    merge a l m r
  end

let () =
  let n = read_int () in
  let a = Array.init n (fun _ -> Scanf.scanf "%d " (fun i -> i)) in
  merge_sort a 0 n;
  print_int a.(0);
  for i = 1 to n - 1 do
    Printf.printf " %d" a.(i);
  done;
  print_newline ();
  Printf.printf "%d\n" !cnt

Merge Sort

Write a program of a Merge Sort algorithm implemented by the following pseudocode. You should also report the number of comparisons in the Merge function.

Merge(A, left, mid, right)
n1 = mid - left;
n2 = right - mid;
create array L[0...n1], R[0...n2]
for i = 0 to n1-1
do L[i] = A[left + i]
for i = 0 to n2-1
do R[i] = A[mid + i]
L[n1] = SENTINEL
R[n2] = SENTINEL
i = 0;
j = 0;
for k = left to right-1
if L[i] <= R[j]
then A[k] = L[i]
i = i + 1
else A[k] = R[j]
j = j + 1

Merge-Sort(A, left, right){
if left+1 < right
then mid = (left + right)/2;
call Merge-Sort(A, left, mid)
call Merge-Sort(A, mid, right)
call Merge(A, left, mid, right)

Input

In the first line n is given. In the second line, n integers are given.

Output

In the first line, print the sequence S. Two consequtive elements should be separated by a space character.

In the second line, print the number of comparisons.

Constraints

n ≤ 500000

0 ≤ an element in S ≤ 109

Sample Input 1

10
8 5 9 2 6 3 7 1 10 4

Sample Output 1

1 2 3 4 5 6 7 8 9 10
34

Notes


let cnt = ref 0

let merge a l m r =
  let ai = Array.make (m - l + 1) max_int in
  for i = 0 to m - l - 1 do
    ai.(i) <- a.(l + i)
  done;
  let aj = Array.make (r - m + 1) max_int in
  for i = 0 to r - m - 1 do
    aj.(i) <- a.(m + i)
  done;
  let i = ref 0 in
  let j = ref 0 in
  for k = l to r - 1 do
    incr cnt;
    if ai.(!i) <= aj.(!j) then begin
      a.(k) <- ai.(!i);
      incr i;
    end else begin
      a.(k) <- aj.(!j);
      incr j;
    end
  done

let rec merge_sort a l r =
  if (l + 1) < r then begin
    let m = (l + r) / 2 in
    merge_sort a l m;
    merge_sort a m r;
    merge a l m r
  end

let () =
  let n = read_int () in
  let a = Array.init n (fun _ -> Scanf.scanf "%d " (fun i -> i)) in
  merge_sort a 0 n;
  print_int a.(0);
  for i = 1 to n - 1 do
    print_string " ";
    print_int a.(i);
  done;
  print_newline ();
  print_int !cnt;
  print_newline ()


let rev_iter (f : int -> unit) (a : int array) =
  for i = Array.length a - 1 downto 0 do
    f a.(i)
  done

let counting_sort a b k =
  let c = Array.make (k + 1) 0 in
  Array.iter (fun e -> c.(e) <- c.(e) + 1) a;
  Array.iteri (fun i _ -> if i <> 0 then c.(i) <- c.(i) + c.(i-1)) c;
  rev_iter (fun e -> b.(c.(e)-1) <- e; c.(e) <- c.(e) - 1) a

let () =
  let n = read_int () in
  let a = Array.init n (fun _ -> Scanf.scanf "%d " (fun e -> e)) in
  let b = Array.make n 0 in
  counting_sort a b 10000;
  Array.iteri (fun i e -> if i <> 0 then print_string " "; print_int e) b;
  print_newline ()

Counting Sort

Counting sort can be used for sorting elements in an array which each of the n input elements is an integer in the range 0 to k. The idea of counting sort is to determine, for each input element x, the number of elements less than x as C[x]. This information can be used to place element x directly into its position in the output array B. This scheme must be modified to handle the situation in which several elements have the same value. Please see the following pseudocode for the detail:

Counting-Sort(A, B, k)
1 for i = 0 to k
2 do C[i] = 0
3 for j = 1 to length[A]
4 do C[A[j]] = C[A[j]]+1
5 /* C[i] now contains the number of elements equal to i */
6 for i = 1 to k
7 do C[i] = C[i] + C[i-1]
8 /* C[i] now contains the number of elements less than or equal to i */
9 for j = length[A] downto 1
10 do B[C[A[j]]] = A[j]
11 C[A[j]] = C[A[j]]-1

Write a program which sorts elements of given array ascending order based on the counting sort.

Input

The first line of the input includes an integer n, the number of elements in the sequence.

In the second line, n elements of the sequence are given separated by spaces characters.

Output

Print the sorted sequence. Two contiguous elements of the sequence should be separated by a space character.

Constraints

1 ≤ n ≤ 2,000,000

0 ≤ A[i] ≤ 10,000

Sample Input 1

7
2 5 1 3 2 3 0

Sample Output 1

0 1 2 2 3 3 5


let counting_sort a b k n =
  let c = Array.make (k + 1) 0 in
  Array.iter (fun e -> c.(e) <- c.(e) + 1) a;
  for i = 1 to k do
    c.(i) <- c.(i) + c.(i-1)
  done;
  for i = n - 1 downto 0 do
    c.(a.(i)) <- c.(a.(i)) - 1;
    b.(c.(a.(i))) <- a.(i);
  done

let () =
  let n = read_int () in
  let a = Array.init n (fun _ -> Scanf.scanf "%d " (fun e -> e)) in
  let b = Array.make n 0 in
  counting_sort a b 10000 n;
  print_int b.(0);
  for i = 1 to n - 1 do
    print_string " "; print_int b.(i);
  done;
  print_newline ()


let n=read_int()open Array
let a=init n(fun _->Scanf.scanf"%d "(fun e->e))and b=make n 0and c=make 10001 0;;iter(fun e->c.(e)<-c.(e)+1)a;iteri(fun i _->if i<>0then c.(i)<-c.(i)+c.(i-1))c;for i=n-1downto 0do c.(a.(i))<-c.(a.(i))-1;b.(c.(a.(i)))<-a.(i);done;print_int b.(0);for i=1to n-1do print_string" ";print_int b.(i);done;print_newline()


let partition (a : int array) p r =
  let x = a.(r) in
  let swap i j = let t = a.(i) in a.(i) <- a.(j); a.(j) <- t
  in
  let rec doit i j =
    if j >= r then i
    else begin
      if a.(j) <= x then (swap (i + 1) j; doit (i + 1) (j + 1))
      else doit i (j + 1)
    end
  in
  let i = doit (p - 1) p in
  swap (i + 1) r;
  i + 1

let () =
  let n = read_int () in
  let a = Array.init n (fun _ -> Scanf.scanf "%d " (fun i -> i)) in
  let k = partition a 0 (n - 1) in
  Array.iteri (fun i e ->
    Printf.printf (if i = 0 then "%d" else if i = k then " [%d]" else " %d") e) a;
  print_newline ()

Partition

Quick sort is based on the Divide-and-conquer approach. In QuickSort(A, p, r), first, a procedure Partition(A, p, r) divides an array A[p..r] into two subarrays A[p..q-1] and A[q+1..r] such that each element of A[p..q-1] is less than or equal to A[q], which is, inturn, less than or equal to each element of A[q+1..r]. It also computes the index q.

In the conquer processes, the two subarrays A[p..q-1] and A[q+1..r] are sorted by recursive calls of QuickSort(A, p, q-1) and QuickSort(A, q+1, r).

Your task is to read a sequence A and perform the Partition based on the following pseudocode:

Partition(A, p, r)
1 x = A[r]
2 i = p-1
3 for j = p to r-1
4 do if A[j] <= x
5 then i = i+1
6 exchange A[i] and A[j]
7 exchange A[i+1] and A[r]
8 return i+1

Note that, in this algorithm, Partition always selects an element A[r] as a pivot element around which to partition the array A[p..r].

Input

The first line of the input includes an integer n, the number of elements in the sequence A.

In the second line, Ai (i = 1,2,...,n), elements of the sequence are given separated by space characters.

Output

Print the sorted sequence. Two contiguous elements of the sequence should be separated by a space character. The element which is selected as the pivot of the partition should be indicated by [  ].

Constraints

1 ≤ n ≤ 100,000

0 ≤ Ai ≤ 100,000

Sample Input 1

12
13 19 9 5 12 8 7 4 21 2 6 11

Sample Output 1

9 5 8 7 4 2 6 [11] 21 13 19 12


let partition (a : int array) p r =
  let x = a.(r) in
  let swap i j = let t = a.(i) in a.(i) <- a.(j); a.(j) <- t
  in
  let rec doit i j =
    if j = r then (swap (i + 1) r; i + 1)
    else if a.(j) <= x then (swap (i + 1) j; doit (i + 1) (j + 1))
    else doit i (j + 1)
  in doit (p - 1) p

let () =
  let n = read_int () in
  let a = Array.init n (fun _ -> Scanf.scanf "%d " (fun i -> i)) in
  let k = partition a 0 (n - 1) in
  Array.iteri (fun i e -> Printf.printf (if i = 0 then "%d" else if i = k then " [%d]" else " %d") e) a;
  print_newline ()


let partition (a : int array) p r =
  let i = ref p in
  for j = p to r - 1 do
    if a.(j) <= a.(r) then begin
      let tmp = a.(!i) in
      a.(!i) <- a.(j);
      a.(j) <- tmp;
      incr i;
    end
  done;
  let tmp = a.(!i) in
  a.(!i) <- a.(r);
  a.(r) <- tmp;
  !i

let () =
  let n = read_int () in
  let a = Array.init n (fun _ -> Scanf.scanf "%d " (fun i -> i)) in
  let k = partition a 0 (n - 1) in
  print_int a.(0);
  for i = 1 to n - 1 do
    if i = k then (print_string " ["; print_int a.(i); print_string "]")
    else (print_string " "; print_int a.(i))
  done;
  print_newline ()


let quick_sort (a : (int * char * int) array) cmp =
  let rec partition p r =
    let swap i j = let t = Array.get a i in Array.set a i (Array.get a j); Array.set a j t
    in
    let rec exchange i j =
      if j >= r then (swap (i + 1) r; i + 1)
      else if cmp a.(j) a.(r) <= 0 then (swap (i + 1) j; exchange (i + 1) (j + 1))
      else exchange i (j + 1)
    in exchange (p - 1) p
  and doit p r =
    if p < r then begin
      let q = partition p r in
      doit p (q - 1);
      doit q r
    end in
  doit 0 (Array.length a - 1)

let stable_p (a : (int * char * int) array) n =
  let rec doit i =
    if i = n - 1 then true
    else if (fun (xi, _, xd) (yi, _, yd) -> xd = yd && xi > yi) a.(i) a.(i+1) then false
    else doit (i + 1)
  in doit 0

let split str delim =
  let rec doit s acc =
    match
      try Some (String.rindex s delim) with _ -> None
    with
    | None -> s :: acc
    | Some i ->
        let s1 = String.sub s 0 i in
        doit s1 (String.sub s (i + 1) (String.length s - String.length s1 - 1) :: acc)
  in doit str []

let () =
  let n = read_int () in
  let a = Array.init n (fun i ->
    match split (read_line ()) ' ' with
    | [c; d] -> (i, c.[0], int_of_string d)
    | _ -> exit 1
  ) in
  quick_sort a (fun (_, _, x) (_, _, y) -> compare x y);
  print_endline (if stable_p a n then "Stable" else "Not stable");
  Array.iter (fun (_, c, d) -> Printf.printf "%c %d\n" c d) a

Quick Sort

Let's arrange a deck of cards. Your task is to sort totally n cards. A card consists of a part of a suit (S, H, C or D) and an number. Write a program which sorts such cards based on the following pseudocode:

Partition(A, p, r)
1 x = A[r]
2 i = p-1
3 for j = p to r-1
4 do if A[j] <= x
5 then i = i+1
6 exchange A[i] and A[j]
7 exchange A[i+1] and A[r]
8 return i+1

Quicksort(A, p, r)
1 if p < r
2 then q = Partition(A, p, r)
3 run Quicksort(A, p, q-1)
4 run Quicksort(A, q+1, r)

Here, A is an array which represents a deck of cards and comparison operations are performed based on the numbers.

Your program should also report the stability of the output for the given input (instance). Here, 'stability of the output' means that: cards with the same value appear in the output in the same order as they do in the input (instance).

Input

The first line contains an integer n, the number of cards.

n cards are given in the following lines. Each card is given in a line and represented by a pair of a character and an integer separated by a single space.

Output

In the first line, print the stability ("Stable" or "Not stable") of this output.

In the following lines, print the arranged cards in the same manner of that of the input.

Constraints

1 ≤ n ≤ 100,000

1 ≤ the number of a card ≤ 109

There are no identical card in the input

Sample Input 1

6
D 3
H 2
D 1
S 3
D 2
C 1

Sample Output 1

Not stable
D 1
C 1
D 2
H 2
D 3
S 3

Sample Input 2

2
S 1
H 1

Sample Output 2

Stable
S 1
H 1


let quick_sort (a : (int * char * int) array) =
  let swap i j = let tmp = a.(i) in a.(i) <- a.(j); a.(j) <- tmp in
  let partition p r =
    let rec exchange = function
      | (i, j) when j = r -> swap i r; i
      | (i, j) when (fun (_, _, x) (_, _, y) -> x - y) a.(j) a.(r) <= 0 -> swap i j; exchange (i + 1, j + 1)
      | (i, j) -> exchange (i, j + 1) in
    exchange (p, p) in
  let rec doit p r =
    if p < r then begin
      let q = partition p r in
      doit p (q - 1);
      doit q r
    end in
  doit 0 (Array.length a - 1)

let stable_p (a : (int * char * int) array) n =
  let rec doit i =
    if i = n then true
    else if (fun (xi, _, xd) (yi, _, yd) -> xd = yd && xi > yi) a.(i-1) a.(i) then false
    else doit (i + 1) in
  doit 1

let split str delim =
  let open String in
  let rec doit s acc =
    match
      try Some (rindex s delim) with _ -> None
    with
    | None -> s :: acc
    | Some i -> doit (sub s 0 i) (sub s (i + 1) (length s - i - 1) :: acc) in
  doit str []

let () =
  let n = read_int () in
  let a = Array.init n (fun i ->
    match split (read_line ()) ' ' with
    | [c; d] -> (i, c.[0], int_of_string d)
    | _ -> exit 1) in
  quick_sort a;
  print_endline (if stable_p a n then "Stable" else "Not stable");
  Array.iter (fun (_, c, d) -> Printf.printf "%c %d\n" c d) a


type t = {
  id : int;
  ch : char;
  num : int;
}

let a = Array.make 100001 { id = 0; ch = '\000'; num = 0 }

let rec partitoin r = function
  | (i, j) when j = r ->
    let tmp = a.(i) in
    a.(i) <- a.(j);
    a.(j) <- tmp;
    i
  | (i, j) when a.(j).num <= a.(r).num ->
    let tmp = a.(i) in
    a.(i) <- a.(j);
    a.(j) <- tmp;
    partitoin r (i + 1, j + 1)
  | (i, j) ->
    partitoin r (i, j + 1)

let rec quick_sort p r =
  if p < r then begin
    let q = partitoin r (p, p) in
    quick_sort p (q - 1);
    quick_sort q r
  end

let rec stable_str n i =
  if i = n then "Stable"
  else if a.(i-1).num = a.(i).num && a.(i-1).id > a.(i).id then "Not stable"
  else stable_str n (i + 1)

let rec read i n =
  if i < n then begin
    begin match Str.split (Str.regexp " ") (read_line ()) with
    | [c; d] -> a.(i) <- { id = i; ch = c.[0]; num = int_of_string d }
    | _ -> exit 1
    end;
    read (i + 1) n
  end

let rec print i n =
  if i < n then begin
    print_char a.(i).ch;
    print_string " ";
    print_int a.(i).num;
    print_string "\n";
    print (i + 1) n
  end

let () =
  let n = read_int () in
  read 0 n;
  quick_sort 0 (n - 1);
  print_endline (stable_str n 1);
  print 0 n


let quick_sort (a : (int * char * int) array) cmp =
  let swap i j = let tmp = a.(i) in a.(i) <- a.(j); a.(j) <- tmp in
  let partition p r =
    let rec exchange = function
      | (i, j) when j = r -> swap i r; i
      | (i, j) when cmp a.(j) a.(r) <= 0 -> swap i j; exchange (i + 1, j + 1)
      | (i, j) -> exchange (i, j + 1) in
    exchange (p, p) in
  let rec doit p r =
    if p < r then begin
      let q = partition p r in
      doit p (q - 1);
      doit q r
    end in
  doit 0 (Array.length a - 1)

let stable_p (a : (int * char * int) array) n =
  let rec doit i =
    if i = n then true
    else if (fun (xi, _, xd) (yi, _, yd) -> xd = yd && xi > yi) a.(i-1) a.(i) then false
    else doit (i + 1) in
  doit 1

let split_on_char sep s =
  let open String in
  let r = ref [] in
  let j = ref (length s) in
  for i = length s - 1 downto 0 do
    if get s i = sep then begin
      r := sub s (i + 1) (!j - i - 1) :: !r;
      j := i
    end
  done;
  sub s 0 !j :: !r

let () =
  let n = read_int () in
  let read i =
    match split_on_char ' ' (read_line ()) with
    | [c; d] -> (i, c.[0], int_of_string d)
    | _ -> exit 1 in
  let a = Array.init n read in
  quick_sort a (fun (_, _, x) (_, _, y) -> compare x y);
  print_endline (if stable_p a n then "Stable" else "Not stable");
  Array.iter (fun (_, c, d) -> Printf.printf "%c %d\n" c d) a


let quick_sort (a : (int * char * int) array) n cmp =
  let swap i j = let tmp = a.(i) in a.(i) <- a.(j); a.(j) <- tmp in
  let partition p r =
    let i = ref p in
    for j = p to r - 1 do
      if cmp a.(j) a.(r) <= 0 then begin
        swap !i j;
        incr i;
      end
    done;
    swap !i r;
    !i in
  let rec doit p r =
    if p >= r then () else
    let q = partition p r in
    doit p (q - 1);
    doit q r in
  doit 0 (n - 1)

let stable_p (a : (int * char * int) array) n =
  try
    for i = 1 to n - 1 do
      if (fun (xi, _, xd) (yi, _, yd) -> xd = yd && xi > yi) a.(i-1) a.(i) then raise Exit
    done;
    true
  with Exit -> false

let split_on_char sep s =
  let open String in
  let r = ref [] in
  let j = ref (length s) in
  for i = length s - 1 downto 0 do
    if get s i = sep then begin
      r := sub s (i + 1) (!j - i - 1) :: !r;
      j := i
    end
  done;
  sub s 0 !j :: !r

let () =
  let n = read_int () in
  let a = Array.init n (fun i ->
    match read_line () |> split_on_char ' ' with
    | [c; d] -> (i, c.[0], int_of_string d)
    | _ -> assert false) in
  quick_sort a n (fun (_, _, x) (_, _, y) -> compare x y);
  print_endline (if stable_p a n then "Stable" else "Not stable");
  Array.iter (fun (_, c, d) -> Printf.printf "%c %d\n" c d) a


module type Comparable = sig
  type t
  val compare : t -> t -> int
end

module Make(Cmp : Comparable) = struct
  type tree = Nil | Node of Cmp.t * tree * tree

  let create () = Nil

  let insert x t =
    let rec doit = function
      | Nil -> Node (x, Nil, Nil)
      | (Node (y, _, _)) as d when x = y -> d
      | Node (y, l, r) when Cmp.compare x y < 0 -> Node (y, doit l, r)
      | Node (y, l, r) -> Node (y, l, doit r)
    in
    doit t

  let preorder f t =
    let rec doit = function
      | Nil -> ()
      | Node (x, l, r) -> (f x; doit l; doit r)
    in
    doit t

  let inorder f t =
    let rec doit = function
      | Nil -> ()
      | Node (x, l, r) -> (doit l; f x; doit r)
    in
    doit t
end

module T = Make(struct type t = int let compare x y = x - y end)

let print t =
  let f e = print_string " "; print_int e in
  T.inorder f t;
  print_newline ();
  T.preorder f t;
  print_newline ()

let () =
  let m = read_int () in
  let rec read i t =
    if i < m then begin
      let op = Scanf.scanf "%s " (fun i -> i) in
      if op = "print" then (print t; read (i + 1) t)
      else
        let k = Scanf.scanf "%d " (fun i -> i) in
        read (i + 1) (T.insert k t)
    end
  in
  read 0 (T.create ())

MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Binary Search Tree I

Search trees are data structures that support dynamic set operations including insert, search, delete and so on. Thus a search tree can be used both as a dictionary and as a priority queue.

Binary search tree is one of fundamental search trees. The keys in a binary search tree are always stored in such a way as to satisfy the following binary search tree property:

Let $x$ be a node in a binary search tree. If $y$ is a node in the left subtree of $x$, then $y.key \leq x.key$. If $y$ is a node in the right subtree of $x$, then $x.key \leq y.key$.

The following figure shows an example of the binary search tree.

For example, keys of nodes which belong to the left sub-tree of the node containing 80 are less than or equal to 80, and keys of nodes which belong to the right sub-tree are more than or equal to 80. The binary search tree property allows us to print out all the keys in the tree in sorted order by an inorder tree walk.

A binary search tree should be implemented in such a way that the binary search tree property continues to hold after modifications by insertions and deletions. A binary search tree can be represented by a linked data structure in which each node is an object. In addition to a key field and satellite data, each node contains fields left, right, and p that point to the nodes corresponding to its left child, its right child, and its parent, respectively.

To insert a new value $v$ into a binary search tree $T$, we can use the procedure insert as shown in the following pseudo code. The insert procedure is passed a node $z$ for which $z.key = v$, $z.left = NIL$, and $z.right = NIL$. The procedure modifies $T$ and some of the fields of $z$ in such a way that $z$ is inserted into an appropriate position in the tree.

1 insert(T, z)
2 y = NIL // parent of x
3 x = 'the root of T'
4 while x ≠ NIL
5 y = x // set the parent
6 if z.key < x.key
7 x = x.left // move to the left child
8 else
9 x = x.right // move to the right child
10 z.p = y
11
12 if y == NIL // T is empty
13 'the root of T' = z
14 else if z.key < y.key
15 y.left = z // z is the left child of y
16 else
17 y.right = z // z is the right child of y

Write a program which performs the following operations to a binary search tree $T$.

insert $k$: Insert a node containing $k$ as key into $T$.

print: Print the keys of the binary search tree by inorder tree walk and preorder tree walk respectively.

You should use the above pseudo code to implement the insert operation. $T$ is empty at the initial state.

Input

In the first line, the number of operations $m$ is given. In the following $m$ lines, operations represented by insert $k$ or print are given.

Output

For each print operation, print a list of keys obtained by inorder tree walk and preorder tree walk in a line respectively. Put a space character before each key.

Constraints

The number of operations $\leq 500,000$

The number of print operations $\leq 10$.

$-2,000,000,000 \leq key \leq 2,000,000,000$

The height of the binary tree does not exceed 100 if you employ the above pseudo code.

The keys in the binary search tree are all different.

Sample Input 1

8
insert 30
insert 88
insert 12
insert 1
insert 20
insert 17
insert 25
print

Sample Output 1

1 12 17 20 25 30 88
30 12 1 20 17 25 88

Reference

Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.


type tree = Nil | Node of int * tree * tree

let create () = Nil

let insert x t =
  let rec doit = function
    | Nil -> Node (x, Nil, Nil)
    | Node (y, l, r) ->
      if x < y then Node (y, doit l, r)
      else Node (y, l, doit r) in
  doit t

let preorder f t =
  let rec doit = function
    | Nil -> ()
    | Node (x, l, r) -> f x; doit l; doit r in
  doit t

let inorder f t =
  let rec doit = function
    | Nil -> ()
    | Node (x, l, r) -> doit l; f x; doit r in
  doit t

let print t =
  inorder (fun e -> print_string " "; print_int e) t;
  print_newline ();
  preorder (fun e -> print_string " "; print_int e) t;
  print_newline ()

let find x t =
  let rec doit = function
    | Nil -> false
    | Node (y, _, _) when x = y -> true
    | Node (y, l, _) when x < y -> doit l
    | Node (_, _, r) -> doit r in
  doit t

let split_on_char sep s =
  let open String in
  let r = ref [] in
  let j = ref (length s) in
  for i = length s - 1 downto 0 do
    if get s i = sep then begin
      r := sub s (i + 1) (!j - i - 1) :: !r;
      j := i
    end
  done;
  sub s 0 !j :: !r

let () =
  let m = read_int () in
  let t = ref (create ()) in
  for _ = 0 to m - 1 do
    match read_line () |> split_on_char ' ' with
    | ["insert"; n] -> t := insert (int_of_string n) !t
    | ["find"; n] -> print_endline (if find (int_of_string n) !t then "yes" else "no")
    | _ -> print !t
  done

Binary Search Tree II

Write a program which performs the following operations to a binary search tree $T$ by adding the find operation to A: Binary Search Tree I.

insert $k$: Insert a node containing $k$ as key into $T$.

find $k$: Report whether $T$ has a node containing $k$.

print: Print the keys of the binary search tree by inorder tree walk and preorder tree walk respectively.

Input

In the first line, the number of operations $m$ is given. In the following $m$ lines, operations represented by insert $k$, find $k$ or print are given.

Output

For each find $k$ operation, print "yes" if $T$ has a node containing $k$, "no" if not.

In addition, for each print operation, print a list of keys obtained by inorder tree walk and preorder tree walk in a line respectively. Put a space character before each key.

Constraints

The number of operations $\leq 500,000$

The number of print operations $\leq 10$.

$-2,000,000,000 \leq key \leq 2,000,000,000$

The height of the binary tree does not exceed 100 if you employ the above pseudo code.

The keys in the binary search tree are all different.

Sample Input 1

10
insert 30
insert 88
insert 12
insert 1
insert 20
find 12
insert 17
insert 25
find 16
print

Sample Output 1

yes
no
1 12 17 20 25 30 88
30 12 1 20 17 25 88

Reference

Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.


type tree = Nil | Node of int * tree * tree

let create () = Nil

let insert x t =
  let rec doit = function
    | Nil -> Node (x, Nil, Nil)
    | Node (y, l, r) ->
      if x < y then Node (y, doit l, r)
      else Node (y, l, doit r) in
  doit t

let preorder f t =
  let rec doit = function
    | Nil -> ()
    | Node (x, l, r) -> f x; doit l; doit r in
  doit t

let inorder f t =
  let rec doit = function
    | Nil -> ()
    | Node (x, l, r) -> doit l; f x; doit r in
  doit t

let print t =
  inorder (fun e -> print_string " "; print_int e) t;
  print_newline ();
  preorder (fun e -> print_string " "; print_int e) t;
  print_newline ()

let find x t =
  let rec doit = function
    | Nil -> false
    | Node (y, _, _) when x = y -> true
    | Node (y, l, _) when x < y -> doit l
    | Node (_, _, r) -> doit r in
  doit t

let delete x t =
  let rec dudu = function
    | Nil -> exit 1
    | Node (x, Nil, _) -> x
    | Node (_, l, _) -> dudu l
  and wa = function
    | Nil -> exit 1
    | Node (_, Nil, r) -> r
    | Node (x, l, r) -> Node (x, wa l, r)
  and doit = function
    | Nil -> exit 1
    | Node (y, l, r) when x = y ->
      if l = Nil then r
      else if r = Nil then l
      else Node (dudu r, l, wa r)
    | Node (y, l, r) when x < y -> Node (y, doit l, r)
    | Node (y, l, r) -> Node (y, l, doit r) in
  doit t

let split_on_char sep s =
  let open String in
  let r = ref [] in
  let j = ref (length s) in
  for i = length s - 1 downto 0 do
    if get s i = sep then begin
      r := sub s (i + 1) (!j - i - 1) :: !r;
      j := i
    end
  done;
  sub s 0 !j :: !r

let () =
  let m = read_int () in
  let t = ref (create ()) in
  for _ = 0 to m - 1 do
    match read_line () |> split_on_char ' ' with
    | ["insert"; n] -> t := insert (int_of_string n) !t
    | ["find"; n] -> print_endline (if find (int_of_string n) !t then "yes" else "no")
    | ["delete"; n] -> t := delete (int_of_string n) !t
    | _ -> print !t
  done

Binary Search Tree III

Write a program which performs the following operations to a binary search tree $T$ by adding delete operation to B: Binary Search Tree II.

insert $k$: Insert a node containing $k$ as key into $T$.

find $k$: Report whether $T$ has a node containing $k$.

delete $k$: Delete a node containing $k$.

print: Print the keys of the binary search tree by inorder tree walk and preorder tree walk respectively.

The operation delete $k$ for deleting a given node $z$ containing key $k$ from $T$ can be implemented by an algorithm which considers the following cases:

If $z$ has no children, we modify its parent $z.p$ to replace $z$ with NIL as its child (delete $z$).

If $z$ has only a single child, we "splice out" $z$ by making a new link between its child and its parent.

If $z$ has two children, we splice out $z$'s successor $y$ and replace $z$'s key with $y$'s key.

Input

In the first line, the number of operations $m$ is given. In the following $m$ lines, operations represented by insert $k$, find $k$, delete $k$ or print are given.

Output

For each find $k$ operation, print "yes" if $T$ has a node containing $k$, "no" if not.

In addition, for each print operation, print a list of keys obtained by inorder tree walk and preorder tree walk in a line respectively. Put a space character before each key

Constraints

The number of operations $\leq 500,000$

The number of print operations $\leq 10$.

$-2,000,000,000 \leq key \leq 2,000,000,000$

The height of the binary tree does not exceed 100 if you employ the above pseudo code.

The keys in the binary search tree are all different.

Sample Input 1

18
insert 8
insert 2
insert 3
insert 7
insert 22
insert 1
find 1
find 2
find 3
find 4
find 5
find 6
find 7
find 8
print
delete 3
delete 7
print

Sample Output 1

yes
yes
yes
no
no
no
yes
yes
1 2 3 7 8 22
8 2 1 3 7 22
1 2 8 22
8 2 1 22

Reference

Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.


type tree = Nil | Node of int * tree * tree

let create () = Nil

let insert x t =
  let rec doit = function
    | Nil -> Node (x, Nil, Nil)
    | Node (y, l, r) ->
      if x < y then Node (y, doit l, r)
      else Node (y, l, doit r) in
  doit t

let preorder f t =
  let rec doit = function
    | Nil -> ()
    | Node (x, l, r) -> f x; doit l; doit r in
  doit t

let inorder f t =
  let rec doit = function
    | Nil -> ()
    | Node (x, l, r) -> doit l; f x; doit r in
  doit t

let print t =
  inorder (fun e -> print_string " "; print_int e) t;
  Printf.printf "\n";
  preorder (fun e -> print_string " "; print_int e) t;
  Printf.printf "\n"

let find x t =
  let rec doit = function
    | Nil -> false
    | Node (y, _, _) when x = y -> true
    | Node (y, l, _) when x < y -> doit l
    | Node (_, _, r) -> doit r in
  doit t

let delete x t =
  let rec balance = function
    | Nil -> assert false
    | Node (x, Nil, r) -> (x, r)
    | Node (x, l, r) ->
      let (m, l) = balance l in
      (m, Node (x, l, r)) in
  let rec doit = function
    | Nil -> assert false
    | Node (y, l, r) ->
      if x = y then
        if l = Nil then r
        else if r = Nil then l
        else
          let (m, r) = balance r in
          Node (m, l, r)
      else if x < y then Node (y, doit l, r)
      else Node (y, l, doit r) in
  doit t

let split_on_char sep s =
  let open String in
  let r = ref [] in
  let j = ref (length s) in
  for i = length s - 1 downto 0 do
    if get s i = sep then begin
      r := sub s (i + 1) (!j - i - 1) :: !r;
      j := i
    end
  done;
  sub s 0 !j :: !r

let () =
  let m = read_int () in
  let t = ref (create ()) in
  for _ = 0 to m - 1 do
    match read_line () |> split_on_char ' ' with
    | ["insert"; n] -> t := insert (int_of_string n) !t
    | ["find"; n] -> print_endline (if find (int_of_string n) !t then "yes" else "no")
    | ["delete"; n] -> t := delete (int_of_string n) !t
    | _ -> print !t
  done


type tree = Nil | Node of int * tree * tree

let create () = Nil

let insert x t =
  let rec doit = function
    | Nil -> Node (x, Nil, Nil)
    | Node (y, l, r) ->
      if x < y then Node (y, doit l, r)
      else Node (y, l, doit r) in
  doit t

let preorder f t =
  let rec doit = function
    | Nil -> ()
    | Node (x, l, r) -> f x; doit l; doit r in
  doit t

let inorder f t =
  let rec doit = function
    | Nil -> ()
    | Node (x, l, r) -> doit l; f x; doit r in
  doit t

let print t =
  inorder (fun e -> print_string " "; print_int e) t;
  print_newline ();
  preorder (fun e -> print_string " "; print_int e) t;
  print_newline ()

let find x t =
  let rec doit = function
    | Nil -> false
    | Node (y, _, _) when x = y -> true
    | Node (y, l, _) when x < y -> doit l
    | Node (_, _, r) -> doit r in
  doit t

let delete x t =
  let rec balance = function
    | Nil -> assert false
    | Node (x, Nil, r) -> (x, r)
    | Node (x, l, r) ->
      let (m, l) = balance l in
      (m, Node (x, l, r)) in
  let rec doit = function
    | Nil -> assert false
    | Node (y, l, r) ->
      if x = y then
        if l = Nil then r
        else if r = Nil then l
        else
          let (m, r) = balance r in
          Node (m, l, r)
      else if x < y then Node (y, doit l, r)
      else Node (y, l, doit r) in
  doit t

let split_on_char sep s =
  let open String in
  let r = ref [] in
  let j = ref (length s) in
  for i = length s - 1 downto 0 do
    if get s i = sep then begin
      r := sub s (i + 1) (!j - i - 1) :: !r;
      j := i
    end
  done;
  sub s 0 !j :: !r

let () =
  let m = read_int () in
  let t = ref (create ()) in
  for _ = 0 to m - 1 do
    match read_line () |> split_on_char ' ' with
    | ["insert"; n] -> t := insert (int_of_string n) !t
    | ["find"; n] -> print_endline (if find (int_of_string n) !t then "yes" else "no")
    | ["delete"; n] -> t := delete (int_of_string n) !t
    | _ -> print !t
  done


type tree = Nil | Node of int * tree * tree

let create () = Nil

let insert x t =
  let rec doit = function
    | Nil -> Node (x, Nil, Nil)
    | Node (y, l, r) ->
      if x < y then Node (y, doit l, r)
      else Node (y, l, doit r) in
  doit t

let preorder f t =
  let rec doit = function
    | Nil -> ()
    | Node (x, l, r) -> f x; doit l; doit r in
  doit t

let inorder f t =
  let rec doit = function
    | Nil -> ()
    | Node (x, l, r) -> doit l; f x; doit r in
  doit t

let print t =
  inorder (fun e -> print_string " "; print_int e) t;
  print_newline ();
  preorder (fun e -> print_string " "; print_int e) t;
  print_newline ()

let find x t =
  let rec doit = function
    | Nil -> false
    | Node (y, _, _) when x = y -> true
    | Node (y, l, _) when x < y -> doit l
    | Node (_, _, r) -> doit r in
  doit t

let delete x t =
  let rec doit = function
    | Nil -> assert false
    | Node (y, l, r) ->
      if x = y then
        if l = Nil then r
        else if r = Nil then l
        else
          let rec balance = function
            | Nil -> assert false
            | Node (x, Nil, r) -> (x, r)
            | Node (x, l, r) ->
              let (m, l) = balance l in
              (m, Node (x, l, r)) in
          let (m, r) = balance r in
          Node (m, l, r)
      else if x < y then Node (y, doit l, r)
      else Node (y, l, doit r) in
  doit t

let split_on_char sep s =
  let open String in
  let r = ref [] in
  let j = ref (length s) in
  for i = length s - 1 downto 0 do
    if get s i = sep then begin
      r := sub s (i + 1) (!j - i - 1) :: !r;
      j := i
    end
  done;
  sub s 0 !j :: !r

let () =
  let m = read_int () in
  let t = ref (create ()) in
  for _ = 0 to m - 1 do
    match read_line () |> split_on_char ' ' with
    | ["insert"; n] -> t := insert (int_of_string n) !t
    | ["find"; n] -> print_endline (if find (int_of_string n) !t then "yes" else "no")
    | ["delete"; n] -> t := delete (int_of_string n) !t
    | _ -> print !t
  done


let swap a i j =
    let temp = a.(i) in
    a.(i) <- a.(j);
    a.(j) <- temp
;;

let i = ref 0;;

let extract (a:int array) =
    Printf.printf "%d\n" a.(0);
    a.(0) <- a.(!i);
    let rec downheap h j =
      let largest = ref j in
      if j*2 <= h then
        begin
          if a.(j*2-1) > a.(j-1) then largest := j*2;
          if j*2+1 <= h && a.(j*2) > a.(!largest-1) then largest := j*2+1;
          if !largest != j then
            begin
              swap a (!largest-1) (j-1);
              downheap h (!largest)
            end
        end
    in downheap !i 1;i := !i-1
;;

let insert (a:int array) n =
    a.(!i+1) <- n;
    let rec upheap j =
        if j = 1 then ()
        else
          begin
            if a.(j/2-1) < a.(j-1) then swap a (j/2-1) (j-1)
            ;upheap (j/2)
          end
    in upheap (!i+2);
    i := !i+1

let () =
  let l = Array.make 2000000 0 in
  let rec read () =
      let op = Scanf.scanf "%s " (fun x -> x) in
      if op = "insert" then
        begin
              let n = Scanf.scanf "%d " (fun x -> x) in
              insert l n;read ()
        end
      else if op = "extract" then begin extract l;read () end
  in read ()
;;

MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Priority Queue

A priority queue is a data structure which maintains a set $S$ of elements, each of with an associated value (key), and supports the following operations:

$insert(S, k)$: insert an element $k$ into the set $S$

$extractMax(S)$: remove and return the element of $S$ with the largest key

Write a program which performs the $insert(S, k)$ and $extractMax(S)$ operations to a priority queue $S$.
The priority queue manages a set of integers, which are also keys for the priority.

Input

Multiple operations to the priority queue $S$ are given. Each operation is given by "insert $k$", "extract" or "end" in a line. Here, $k$ represents an integer element to be inserted to the priority queue.

The input ends with "end" operation.

Output

For each "extract" operation, print the element extracted from the priority queue $S$ in a line.

Constraints

The number of operations $\leq 2,000,000$

$0 \leq k \leq 2,000,000,000$

Sample Input 1

insert 8
insert 2
extract
insert 10
extract
insert 11
extract
extract
end

Sample Output 1

8
10
11
2


let last_i = ref 0

let parent i = int_of_float (floor (float_of_int i) /. 2.)

let left i = 2*i

let right i = 2*i + 1

let swap i j t = let tmp = t.(i) in t.(i) <- t.(j); t.(j) <- tmp

let extract (t : int array) =
  let ret = t.(1) in
  t.(1) <- t.(!last_i);
  decr last_i;
  let rec max_heapify i =
    let l = left i in
    let r = right i in
    let m = if l <= !last_i && t.(l) > t.(i) then l else i in
    let m = if r <= !last_i && t.(r) > t.(m) then r else m in
    if i = m then ()
    else begin
      let tmp = t.(i) in t.(i) <- t.(m); t.(m) <- tmp;
      max_heapify m
    end in
  max_heapify 1;
  ret

let insert x (t : int array) =
  incr last_i;
  t.(!last_i) <- x;
  let rec doit i =
    if i <= 1 || t.(parent i) >= t.(i) then ()
    else begin
      let pi = parent i in
      let tmp = t.(i) in t.(i) <- t.(pi); t.(pi) <- tmp;
      doit pi
    end in
  doit !last_i

let split_on_char sep s =
  let open String in
  let r = ref [] in
  let j = ref (length s) in
  for i = length s - 1 downto 0 do
    if get s i = sep then begin
      r := sub s (i + 1) (!j - i - 1) :: !r;
      j := i
    end
  done;
  sub s 0 !j :: !r

let () =
  let t = Array.make 2000001 0 in
  while true do
    match read_line () |> split_on_char ' ' with
    | ["extract"] -> extract t |> Printf.printf "%d\n"
    | ["insert"; n] -> insert (int_of_string n) t
    | _ -> exit 0
  done