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

let a =
  let num = 1000000 in
  let p = Array.init (num+1) (fun x -> 1) in
  let rec loop i =
    if i*i < num then
      begin
        for_range (i+i) num i (fun x -> p.(x) <- 0);
        loop (i+2)
      end
  in
  p.(0) <- 0; p.(1)<-(0);
  for_range 4 num 2 (fun x -> p.(x) <- 0);
  loop 3;
  let rec read () =
    try let n = read_int () in
        Printf.printf "%d\n" (Array.fold_left (+) 0 (Array.sub p 0 (n+1)));
        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.


module Cache = struct
  let create size = Array.make size None

  let find_or_add tbl n f =
    match tbl.(n) with
    | Some v -> v
    | None ->
       let v = f n in
       tbl.(n) <- Some v;
       v
end

let is_prime n memo =
  let rec is_prime_inner n r =
    match r with
      1 -> true
    | _ ->
       match n mod r with
         0 -> false
       | _ -> is_prime_inner n (r-1)
  in
  match memo.(n) with
  | Some v -> v
  | None ->
     let a = is_prime_inner n (int_of_float (floor (sqrt (float_of_int n)))) in
     memo.(n) <- Some a;
     a

let make_list f t step =
  let rec make_list_inner c t lst =
    if c >= t then lst else make_list_inner (c+step) t (c::lst)
  in
  make_list_inner f t []

let map f l = List.rev (List.rev_map f l)

let solve = function
  | 1 -> 0
  | 2 -> 1
  | n ->
     let memo = Cache.create 1000000 in
     List.fold_left (fun x y -> x + y) 0 (map (fun x -> if is_prime x memo then 1 else 0) (make_list 3 n 2))

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


let id x = x

let rec iteri f s t = if s > t then () else begin f s; iteri f (s + 1) t end

let rec read n = if n <= 0 then ([],[])
                 else let x, y = Scanf.scanf "%d,%d\n" (fun x y -> (x, y)) in
                      let (xs, ys) = read (n - 1) in (x::xs, y::ys)

let solve dp vs ws n w =
  iteri (fun i ->
         iteri (fun j ->
                if j >= ws.(i) then dp.(i+1).(j) <- max dp.(i).(j) (dp.(i).(j - ws.(i)) + vs.(i))
                else dp.(i+1).(j) <- dp.(i).(j)) 0 w) 0 (n - 1)

let rec min_w dp i j v =
  if dp.(i).(j) = v then min_w dp i (j - 1) v else j + 1

let _ =
  let cnt = ref 0 in
  try
    while true do
      let w = Scanf.scanf "%d\n" id in
      if w = 0 then
        raise End_of_file
      else
        let n = Scanf.scanf "%d\n" id in
        let dp = Array.make_matrix (n + 1) (w + 1) 0 in
        let vs', ws' = read n in
        let vs = Array.of_list vs' in
        let ws = Array.of_list ws' in
        solve dp vs ws n w;
        incr cnt;
        Printf.printf "Case %d:\n" !cnt;
        Printf.printf "%d\n" (dp.(n).(w));
        Printf.printf "%d\n" (min_w dp n w dp.(n).(w))
    done
  with
    End_of_file -> ()

泥棒

宝物がたくさん収蔵されている博物館に、泥棒が大きな風呂敷を一つだけ持って忍び込みました。盗み出したいものはたくさんありますが、風呂敷が耐えられる重さが限られており、これを超えると風呂敷が破れてしまいます。そこで泥棒は、用意した風呂敷を破らず且つ最も価値が高くなるようなお宝の組み合わせを考えなくてはなりません。

風呂敷が耐えられる重さ W、および博物館にある個々のお宝の価値と重さを読み込んで、重さの総和が W を超えない範囲で価値の総和が最大になるときの、お宝の価値総和と重さの総和を出力するプログラムを作成してください。ただし、価値の総和が最大になる組み合わせが複数あるときは、重さの総和が小さいものを出力することとします。

Input

複数のデータセットが与えられます。各データセットは以下のような形式で与えられます。

W
N
v1,w1
v2,w2
:
vN,wN

１行目に風呂敷の耐えられる重さを表す整数 W (W ≤ 1,000)、２行目にお宝の数 N (1 ≤ N ≤ 1,000) が与えられます。続く N 行に i 番目のお宝の価値を表す整数 vi (0 ≤ vi ≤ 10,000) とその重さを表す整数 wi (0 ≤ wi ≤ W) の組がそれぞれ１行に与えられます。

W が 0 のとき入力の最後とします。データセットの数は 50 を超えません。

Output

各データセットに対して以下のように出力して下さい。

Case データセットの番号:
風呂敷に入れたお宝の価値総和
そのときのお宝の重さの総和

Sample Input

50
5
60,10
100,20
120,30
210,45
10,4
50
5
60,10
100,20
120,30
210,45
10,4
0

Output for the Sample Input

Case 1:
220
49
Case 2:
220
49


open List
let m3_cycle_length = 30
let m3_primes = [5; 3; 2]
let m3_cycle = [6; 4; 2; 4; 2; 4; 6; 2]

let wheel_fact limit =
  let slimit = limit in
  let rec wheel_loop limit n nxt result =
  let get_m3_cycle n =
      nth m3_cycle (n mod ((length m3_cycle)))
  in
  if nxt > limit then tl (sort (fun x y -> if x == 0 then 0
                            else if x > y then 1
                            else -1) (rev (result @ m3_primes)))
  else wheel_loop limit (n + 1) (nxt + (get_m3_cycle n)) (nxt :: result)
  in wheel_loop slimit 0 1 []

let sieve xs =
  let rec sieve_loop xs ys =
    let comp_filter n xs =
      List.filter (fun x -> x mod n != 0 && n != x) xs
    in
    match xs with
      [] -> ys
    | x :: xs -> sieve_loop (comp_filter x xs) (x :: ys)
  in
  sieve_loop xs []

let split xs n =
  let rec split_loop xs n ys =
    if n <= 0 then (ys, xs)
    else split_loop (tl xs) (n - 1) (hd xs :: ys)
  in
  split_loop xs n []

let uniq xs =
  let rec uniq_loop xs ys =
    match xs with
      [] -> ys
    | x :: xs -> uniq_loop (filter (fun (l1, l2) -> l1 != fst x && l2 != snd x) xs) (x :: ys)
  in uniq_loop xs []

let goldbach n =
  let rec gold_loop xs ys zs =
    let rec bach_loop x ys =
      match ys with
        [] -> (0, 0)
      | y :: ys -> if n == y + x then
                      if x < y then (x, y) else (y, x)
                   else bach_loop x ys
    in
    match xs with
      [] -> zs
    | x :: xs -> gold_loop xs ys ((bach_loop x ys) :: zs)
  in
  let sieved = sieve (wheel_fact n) in
  let (sieved1, _) = split sieved ((length sieved) / 2) in
  uniq(filter (fun (x, y) -> x != 0 && y != 0) (gold_loop sieved1 sieved []))

let goldbach_length n = length (goldbach n)

let () =
  let rec echo_sub () =
    print_int (goldbach_length(int_of_string(read_line ())));
    print_newline ();
    echo_sub ()
  in
    try echo_sub () with End_of_file -> ()

ゴールドバッハ予想

ゴールドバッハ予想とは「6 以上のどんな偶数も、2 つの素数 (*1) の和として表わすことができる」というものです。

たとえば、偶数の 12 は 12 = 5 + 7 、18 は 18 = 5 + 13 = 7 + 11 などと表すことができます。

和が 134 となる 2 つの素数の組み合せをすべて書き出すと、以下の通りとなります。

134 = 3+131 = 7+127 = 31+103 = 37+97 = 61+73 = 67+67

= 131+3 = 127+7 = 103+31 = 97+37 = 73+61

与えられた数が大きくなると、いくらでも素数の組み合せが見つかるような気がします。しかし、現代数学をもってしてもこの予想を証明することも、反例を作ることもできません(*2)。ちょっと不思議な感じがしますね。

そこで、ゴールドバッハ予想を鑑賞するために、偶数 n を入力とし、和が n となる 2 つの素数の組み合せの数を求めるプログラムを作成してください。

和が n となる素数の組み合せの数とは n = p + q かつ p ≤ q であるような正の素数 p, q の組み合せの数です。上の例からわかるように和が 134 となる素数の組み合せは6 個です。

(*1) 素数とは、1 または自分自身以外に約数を持たない整数のことである。なお、1 は素数ではない。

(*2) 2007 年 2 月現在、5×1017 までの全ての偶数について成り立つことが確かめられている。(Wikipedia)

Input

複数のデータセットの並びが入力として与えられます。入力の終わりはゼロひとつの行で示されます。 各データセットとして、１つの偶数 n (6 ≤ n ≤ 1000000) が１行に与えられます。

データセットの数は 500 を超えません。

Output

データセット毎に素数の組み合せの数を１行に出力します。

Sample Input

134
4330
34808
98792
0

Output for the Sample Input

6
72
274
607


open List
let m3_cycle_length = 30
let m3_primes = [5; 3; 2]
let m3_cycle = [6; 4; 2; 4; 2; 4; 6; 2]

let wheel_fact limit =
  let slimit = limit in
  let rec wheel_loop limit n nxt result =
  let get_m3_cycle n =
      nth m3_cycle (n mod ((length m3_cycle)))
  in
  if nxt > limit then tl (sort (fun x y -> if x == 0 then 0
                            else if x > y then 1
                            else -1) (rev (result @ m3_primes)))
  else wheel_loop limit (n + 1) (nxt + (get_m3_cycle n)) (nxt :: result)
  in wheel_loop slimit 0 1 []

let sieve xs =
  let rec sieve_loop xs ys =
    let comp_filter n xs =
      List.filter (fun x -> x mod n != 0 && n != x) xs
    in
    match xs with
      [] -> ys
    | x :: xs -> sieve_loop (comp_filter x xs) (x :: ys)
  in
  sieve_loop xs []

let split xs n =
  let rec split_loop xs n ys =
    if n <= 0 then (ys, xs)
    else split_loop (tl xs) (n - 1) (hd xs :: ys)
  in
  split_loop xs n []

let uniq xs =
  let rec uniq_loop xs ys =
    match xs with
      [] -> ys
    | x :: xs -> uniq_loop (filter (fun (l1, l2) -> l1 != fst x && l2 != snd x) xs) (x :: ys)
  in uniq_loop xs []

let goldbach n =
  let rec gold_loop xs y =
    match xs with
      []      -> y
    | z :: zs -> try
                   if (z * 2) >= n then
                     if n - z == (find (fun x -> x + z == n) xs)
                     then gold_loop zs (y + 1)
                     else gold_loop zs y
                   else y
                 with
                   Not_found -> gold_loop zs y
  in
  let sieved = sieve (wheel_fact n) in
  gold_loop sieved 0

let () =
  let rec echo_sub () =
    print_int (goldbach(int_of_string(read_line ())));
    print_newline ();
    echo_sub ()
  in
    try echo_sub () with End_of_file -> ()


let read_lines n =
  let rec read_lines n acc =
    if n = 0 then List.rev acc
    else read_lines (pred n) ((read_line ()) :: acc) in
  read_lines n []

let rec solve () =
  let n_conversion_table = int_of_string @@ read_line () in
  if n_conversion_table = 0 then ()
  else
    let create_conversion_map pairs =
      let hash = Hashtbl.create n_conversion_table in
      List.iter
        (fun (from, to_) -> Hashtbl.add hash from to_)
        pairs;
      hash in
    let conversion_table =
      create_conversion_map
      @@ List.map
           (fun line ->
            Scanf.sscanf line "%c %c" (fun from to_ -> (from, to_)))
           (read_lines n_conversion_table) in
    let convert c =
      try Hashtbl.find conversion_table c with Not_found -> c in
    let n_input = int_of_string @@ read_line () in
    List.iter
      (fun line -> print_char @@ convert line.[0])
      (read_lines n_input);
    print_newline ();
    solve ()

let () = solve ()

与えられた変換表にもとづき，データを変換するプログラムを作成しなさい．

データに使われている文字は英字か数字で，英字は大文字と小文字を区別する．変換表に現れる文字の順序に規則性はない．

変換表は空白をはさんで前と後ろの 2 つの文字がある(文字列ではない)．変換方法は，変換表のある行の前の文字がデータに現れたら，そのたびにその文字を後ろの文字に変換し出力する．変換は 1 度だけで，変換した文字がまた変換対象の文字になっても変換しない．変換表に現れない文字は変換せず，そのまま出力する．

入力ファイルには，変換表（最初の n + 1 行）に続き変換するデータ（n + 2 行目以降）が書いてある． 1 行目に変換表の行数 n，続く n 行の各行は，空白をはさんで 2 つの文字，さらに続けて， n + 2 行目に変換するデータの行数 m，続く m 行の各行は 1 文字である． m ≤ 105 とする．出力は，出力例のように途中に空白や改行は入れず 1 行とせよ．

入力例

3

A a

0 5

5 4

10

A

B

C

0

1

4

5

a

b

A

出力例

aBC5144aba

入力

入力は複数のデータセットからなる．n が 0 のとき入力が終了する．データセットの数は 5 を超えない．

出力

データセットごとに、変換後の文字列を１行に出力する．

入力例

3
A a
0 5
5 4
10
A
B
C
0
1
4
5
a
b
A
3
A a
0 5
5 4
10
A
B
C
0
1
4
5
a
b
A
0

出力例

aBC5144aba
aBC5144aba

各データセットの出力（変換後の文字列）の後に改行を入れること．

上記問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。


let solve n =
  let rec solve n max =
    if n = 0 then [[]]
    else
      let rec loop i acc =
        if i > (min n max) then acc
        else
          let cdrs = solve (n - i) i in
          let acc = List.rev_append
                      (List.rev_map (fun cdr -> i :: cdr) cdrs)
                      acc in
          loop (i + 1) acc in
      loop 1 [] in
  solve n n

let () =
  let rec loop () =
    let n = int_of_string @@ read_line () in
    if n = 0 then ()
    else
      let answers = solve n in
      List.iter
        (fun seq ->
         print_endline @@ String.concat " " @@ List.map string_of_int seq)
        answers;
      loop () in
  loop ()

同じ大きさの正方形の紙が n 枚ある.これらの紙の下部を水平に揃えて何列かに並べる.ただし,隣り合う列は左側が右側より低くならないように並べなければならない.例えば, n = 5 のときは,次のような 7 通りの並べ方が可能である.

これらを,各列に並んだ正方形の個数の列で表すことにする.例えば, n = 5 の
ときは,それぞれ,

(5) (4, 1) (3, 2) (3, 1, 1) (2, 2, 1) (2, 1, 1, 1) (1, 1, 1, 1, 1)

と表わされる.

n を入力したとき, 辞書式順序で全て出力するプログラムを作成せよ.n ≤30
とする.ただし, 辞書式順序とは2つの並べ方 (a1, a2 , ..., as) が並べ方 (b1, b2, ..., bt ) に対して, a1 > b1 または, ある整数 i > 1 が存在して a1 = b1 , ..., ai-1 = bi-1 かつ ai > bi が成り立つとき (a1, a2, ..., as) が (b1 , b2, ..., bt) より先に出力されるように並べることである.

入力データ は 1 行からなり,1 行目に n が書かれている.

出力には並べ方を辞書式順序で 1 行に1通りずつ書き最後に改行を入れること. 並べ方は (a1, a2, ..., as) の出力は整数 a1, a2, . . . , as をこの順番に空白で区切って出力すること.

入力例１

5

出力例１

5

4 1

3 2

3 1 1

2 2 1

2 1 1 1

1 1 1 1 1

入力

入力は複数のデータセットからなる．n が 0 のとき入力が終了する．データセットの数は 5 を超えない．

出力

データセットごとに、辞書式順序で全て出力する．

入力例

5
5
0

出力例

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

上記問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。


open Printf
open Scanf

module Pos = struct
    type t = int * int
    let compare = compare
end

module PosSet = MoreLabels.Set.Make(Pos)

let get_trans sign pict =
    let (ox, oy) = List.hd sign in
    let converted = ListLabels.map sign ~f:(fun (x, y) ->
        (x - ox, y - oy)) in
    let (dx, dy) = PosSet.choose (PosSet.filter pict ~f:(fun (px, py) ->
        ListLabels.for_all converted ~f:(fun (x, y) ->
            PosSet.mem (px + x, py + y) pict))) in
    (dx - ox, dy - oy)

let read_npos () = scanf "%d\n" (fun line ->
    let rec loop acc = function
        | 0 -> acc
        | i -> scanf "%d %d\n" (fun x y ->
                loop ((x, y) :: acc) (i - 1)) in
    List.rev (loop [] line))

let _ =
    let rec loop () =
        let sign = read_npos () in
        match sign with
        | [] -> ()
        | _ ->
                let pict = PosSet.of_list (read_npos ()) in
                let (tx, ty) = get_trans sign pict in
                printf "%d %d\n" tx ty;
                loop () in
    loop ()

星座探し

問題

あなたは星空の写真の中から星座を探している．写真には必ず，探したい星座と同じ形・向き・大きさの図形がちょうど一つ含まれている．ただし，写真の中には星座を構成する星以外に余分な星が写っている可能性がある．

例えば，図 1 の星座は図 2 の写真に含まれている（丸で囲んで示した）．与えられた星座の星の座標を x 方向に 2， y 方向に −3 だけ平行移動すると写真の中の位置になる．

探したい星座の形と写真に写っている星の位置が与えられたとき，星座の座標を写真の中の座標に変換するために平行移動するべき量を答えるプログラムを書け．

図 1: 探したい星座

図 2: 星空の写真

入力

入力は複数のデータセットからなる．各データセットは以下の形式で与えられる．

入力の 1 行目には探したい星座を構成する星の個数 m が書かれている．続く m 行には探したい星座を構成する m 個の星の x 座標と y 座標を示す整数が空白区切りで書かれている． m+2 行目には写真に写っている星の個数 n が書かれている．続く n 行には写真に写っている n 個の星の x 座標と y 座標を示す整数が空白区切りで書かれている．

星座を構成する m 個の星の位置はすべて異なる．また，写真に写っている n 個の星の位置はすべて異なる． 1 ≤ m ≤ 200， 1 ≤ n ≤ 1000 である．星の x 座標と y 座標はすべて 0 以上 1000000 以下である．

m が 0　のとき入力の終わりを示す. データセットの数は 5 を超えない．

出力

各データセットの出力は 1 行からなり， 2 個の整数を空白区切りで書く．これらは探したい星座の座標をどれだけ平行移動すれば写真の中の座標になるかを表す．最初の整数が x 方向に平行移動する量，次の整数が y 方向に平行移動する量である．

入出力例

入力例

5
8 5
6 4
4 3
7 10
0 10
10
10 5
2 7
9 7
8 10
10 2
1 2
8 1
6 7
6 0
0 9
5
904207 809784
845370 244806
499091 59863
638406 182509
435076 362268
10
757559 866424
114810 239537
519926 989458
461089 424480
674361 448440
81851 150384
459107 795405
299682 6700
254125 362183
50795 541942
0

出力例

2 -3
-384281 179674

入出力例の１つ目は上の図に対応している．

上記問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。


let (n,k) = Scanf.sscanf (read_line ()) "%d %d" (fun w h -> (w, h))
;;

let table = Array.make (n+4) 0
;;

let rec get_input () =
  let (a, b) = Scanf.sscanf (read_line ()) "%d %d" (fun a b -> (a,b)) in
  table.(a+1) <- b;
  get_input ()
;;

try get_input ()
with End_of_file -> ()
;;

let is_valid x m1 m2 p1 p2 =
  if x = m1 then
    not (x = m2 || x = p1)
  else
    not (x = p1 && x = p2)
;;

let rec ans index m1 m2 p1 p2 k' =
  if table.(index) <> 0 then
    ans (index+1) table.(index) m1 p2 table.(index+3) k'
  else
    let aux x =
      if is_valid x m1 m2 p1 p2 then
        if k' = n - k - 1 then
          1
        else
          ans (index+1) x m1 p2 table.(index + 3) (k'+1)
      else
        0
    in
    ((aux 1 + aux 2) mod 10000 + aux 3) mod 10000
;;

ans 2 table.(1) table.(0) table.(3) table.(4) 0 |> string_of_int |> print_string
;;
print_string "\n";;

パスタ (Pasta)

問題

あなたはパスタが大好物であり，毎日，晩御飯にパスタを作って食べている．あなたはトマトソース，クリームソース，バジルソースの 3 種類のパスタを作ることができる．

N 日間の晩御飯の予定を考えることにした．それぞれの日に 3 種類のパスタから 1 種類を選ぶ．ただし，同じパスタが続くと飽きてしまうので，3 日以上連続して同じパスタを選んではいけない．また，N 日のうちの K 日分のパスタはすでに決めてある．

入力として N の値と，K 日分のパスタの情報が与えられたとき，条件をみたす予定が何通りあるかを 10000 で割った余りを求めるプログラムを作成せよ．

入力

入力は K + 1 行からなる．

1 行目には 2 つの整数 N, K (3 ≦ N ≦ 100，1 ≦ K ≦ N) が空白を区切りとして書かれている．

1 + i 行目 (1 ≦ i ≦ K) には 2 つの整数 Ai, Bi (1 ≦ Ai ≦ N，1 ≦ Bi ≦ 3) が空白を区切りとして書かれている．これは，Ai 日目のパスタはすでに決まっており，Bi = 1 のときはトマトソースであり，Bi = 2 のときはクリームソースであり，Bi = 3 のときはバジルソースであることを表す．Ai (1 ≦ i ≦ K) は全て異なる．与えられる入力データにおいて，条件をみたす予定は 1 通り以上あることが保証されている．

出力

条件をみたす予定が何通りあるかを 10000 で割った余りを 1 行で出力せよ．

入出力例

入力例 1

5 3
3 1
1 1
4 2

出力例 1

6

入出力例 1 において，あなたは 5 日間の予定を考える．1 日目と 3 日目はトマトソースであり，4 日目はクリームソースである．また，3 日以上連続して同じパスタを選んではいけない．これらの条件をみたす予定は 6 通りある．

 1日目

 2日目

 3日目

 4日目

 5日目

予定 1

1

2

1

2

1

予定 2

1

2

1

2

2

予定 3

1

2

1

2

3

予定 4

1

3

1

2

1

予定 5

1

3

1

2

2

予定 6

1

3

1

2

3

この表では，1 はトマトソースを，2 はクリームソースを，3 はバジルソースを表す．

入力例 2

20 5
10 2
4 3
12 1
13 2
9 1

出力例 2

2640

入出力例 2 において，条件をみたす予定は全部で 4112640 通りある．それを 10000 で割った余りである 2640 を出力する．

問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。


let dbg = Printf.printf "[debug]%s"

let max_num = 1_000_000_000

let id = fun x -> x
let tuple2 x y = (x,y)
let succ x = x + 1
let pred x = x - 1

let (++) n m =
  let rec aux i =
    if i = m then [m]
    else i :: aux (i+1) in
  if n > m then [] else aux n

let (++^) n m = n ++ (m-1)

let scan fmt f = Scanf.sscanf (read_line ()) fmt f

let scan_line n =
  let b = Scanf.Scanning.from_string (read_line ()) in
  List.map (fun _ -> Scanf.bscanf b " %d" id) (0++^n)

let scan_lines n fmt f =
  List.map (fun _ -> scan fmt f) (0++^n)

let scan_matrix n m e conv =
  let arr = Array.make_matrix n m e in
  Array.iteri (fun i line ->
      let s = Scanf.Scanning.from_string @@ read_line () in
      Array.iteri (fun j _ ->
          arr.(i).(j) <- Scanf.bscanf s " %s" conv;
        ) line) arr; arr

let between n x m = n <= x && x < m

let string_to_list s =
  List.map (String.get s) (0 ++^ String.length s)

let solve arr =
  let len = Array.length arr  in
  let memo = Array.make_matrix len len None in
  let rec aux n m =
    if n >= m then 0
    else
      match memo.(n).(m) with
      | Some v -> v
      | None ->
        let v =
          (let x = aux (succ n) (pred m) in
           (if x + 2 = m - n +1
            then x + (if abs @@ arr.(n) - arr.(m) <= 1 then 2 else 0)
            else x))
          :: List.map (fun i ->
              aux n i + aux (succ i) m)
            (n ++^ m) |> List.fold_left max 0 in
        memo.(n).(m) <- Some v; v
  in
  aux 0 @@ pred len

let () =
  let rec aux () =
    let n = scan "%d" id in
    if n = 0 then ()
    else
      let arr = Array.of_list @@ scan_line n in
      solve arr |> Printf.printf "%d\n";
      aux () in
  aux ()

Daruma Otoshi

You are playing a variant of a game called "Daruma Otoshi (Dharma Block Striking)".

At the start of a game, several wooden blocks of the same size but with varying weights
are stacked on top of each other, forming a tower.
Another block symbolizing Dharma is placed atop.
You have a wooden hammer with its head thicker than the height of a block,
but not twice that.

You can choose any two adjacent blocks, except Dharma on the top,
differing at most 1 in their weight,
and push both of them out of the stack with a single blow of your hammer.
The blocks above the removed ones then fall straight down,
without collapsing the tower.

You cannot hit a block pair with weight difference of 2 or more,
for that makes too hard to push out blocks while keeping the balance of the tower.
There is no chance in hitting three blocks out at a time,
for that would require superhuman accuracy.

The goal of the game is to remove as many blocks as you can.
Your task is to decide the number of blocks that can be removed
by repeating the blows in an optimal order.

Figure D1. Striking out two blocks at a time

In the above figure, with a stack of four blocks weighing 1, 2, 3, and
1, in this order from the bottom, you can hit middle
two blocks, weighing 2 and 3, out from the stack. The blocks above will
then fall down, and two blocks weighing 1 and the Dharma block will remain.
You can then push out the remaining pair of weight-1 blocks after that.

Input

The input consists of multiple datasets.
The number of datasets is at most 50.
Each dataset is in the following format.

n

w1 w2 … wn

n is the number of blocks, except Dharma on the top.
n is a positive integer not exceeding 300.
wi gives the weight of the i-th block counted from the bottom.
wi is an integer between 1 and 1000, inclusive.

The end of the input is indicated by a line containing a zero.

Output

For each dataset, output in a line the maximum number of blocks you can remove.

Sample Input

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

Output for the Sample Input

4
4
2
12
0


module ArrayL = ArrayLabels
module ListL = ListLabels

let dbg = Printf.printf "[debug]%s"

let max_num = 100_000_000_000

let id = fun x -> x
let tuple2 x y = (x,y)
let tuple3 x y z = (x,y,z)
let succ x = x + 1
let pred x = x - 1

let (++) n m =
  let rec aux i =
    if i = m then [m]
    else i :: aux (i+1) in
  if n > m then [] else aux n

let (++^) n m = n ++ (m-1)

let scan fmt f = Scanf.sscanf (read_line ()) fmt f

let scan_lines n fmt f =
  List.map (fun _ -> scan fmt f) (0++^n)

let scan_matrix n m e conv =
  let arr = Array.make_matrix n m e in
  Array.iteri (fun i line ->
      let s = Scanf.Scanning.from_string @@ read_line () in
      Array.iteri (fun j _ ->
          arr.(i).(j) <- Scanf.bscanf s " %s" conv;
        ) line) arr; arr

let between n x m = n <= x && x < m

let string_to_list s =
  List.map (String.get s) (0 ++^ String.length s)

let split_on_char s c =
  Str.split (Str.regexp (String.make 1 c)) s

let () =
  let rec aux () =
    let n = scan "%d" id in
    if n <> 0 then
      begin
        let ls = scan_lines n "%s %s" tuple2 in
        let arr = Array.make (24*60*60+60*60+2) 0 in
        ListL.iter ls ~f:(fun (s0, s1) ->
            (match List.map int_of_string @@ split_on_char s0 ':' with
             | a::b::c:: _ ->arr.(60*60*a+60*b+c) <- succ arr.(60*60*a+60*b+c)
             |_ -> ());
            match List.map int_of_string @@ split_on_char s1 ':' with
            | a::b::c::_ -> arr.(60*60*a+60*b+c) <- pred arr.(60*60*a+60*b+c)
            | _ -> ());
        ListL.iter (1 ++^ (24*60*60+60*60+2)) ~f:(fun  i->
            arr.(i) <- arr.(pred i) + arr.(i));
        Array.fold_left max 0 arr |> Printf.printf "%d\n";
        aux()
      end
  in
  aux ()

Osaki

大崎

English text is not available in this practice contest.

山手線は東京 23 区内に敷設されている環状鉄道路線である．総路線距離は 34.5km であり，1 周にはおよそ 1 時間を要する．駅は全部で 29 駅存在する．ラインカラーはウグイス色である．ピーク時の混雑率は 200% を超え，日本の鉄道路線の中で最も混雑している路線の 1 つである．最も混雑する時間帯では 3 分に 1 本の列車が走っており，東京に初めて来た人々はその光景に驚くものである．

鉄子さんは山手線を愛してやまない生粋の鉄道好きである．ある日，彼女は愛読書である JR 時刻表を読みながら次の疑問に至った．「山手線では一日に何台の車両が使われているのだろう？」

彼女は時刻表から運行に最低限必要な車両の台数を割り出そうとした．しかし，列車の本数が非常に多かったので，彼女一人の力では到底数え切れそうにない．そこで彼女は優秀なプログラマーであるあなたに助けを求めた．

あなたの仕事は与えられた時刻表から山手線の運行に要する車両の最低台数を求めるプログラムを書くことである．山手線は環状路線であることから，その時刻表は便宜上「大崎駅」を始発駅および終着駅として表記されることが多い．そのため，彼女から渡された時刻表にも各列車の大崎駅における発時刻および着時刻のみが記されている．

なお，実際の山手線では起こりえないが，状況設定を簡単にするため，ここでは大崎駅の到着直後に列車が大崎駅を出発可能であると考えることにする．また，鉄子さんが写した時刻に誤りがあったり，鉄子さんの妄想によって勝手に加えられた列車が時刻表に紛れ込んだりしている場合もあるが，あなたはそれらを見抜くことができないので，あくまでも書かれたとおりの時刻に対して台数を求めなければならない．

きちんと動作するプログラムを書けば，彼女が列車内デートに誘ってくれるかもしれない．もっとも，誘いに乗るか断るかはあなた次第であるが．

Input

入力は複数のデータセットから構成される．各データセットは次の形式になっている．

n

hh:mm:ss hh:mm:ss

hh:mm:ss hh:mm:ss

...

hh:mm:ss hh:mm:ss

1 行目の整数 n は時刻表に含まれる列車の本数である．この値は 10,000 を超えないことが保証されている．2 行目から n + 1 行目までの n 行には各列車の大崎駅の発時刻および着時刻がこの順番で与えられ，発時刻と着時刻の間は 1 つの空白で区切られている．各時刻は hh:mm:ss の形式で表現され，hh が時，mm が分，ss が秒を表している．それぞれの値の範囲は 0 ≦ hh < 24, 0 ≦ mm < 60, 0 ≦ ss < 60である．これらの数値は全て 2 桁となるように，必要に応じて先頭に 0 が付け加えられている．

夜の 24:00 をまたいで運行されるような列車は含まれない．したがって，常に発時刻は常に着時刻よりも前の時刻である．

入力の終了は n = 0 によって示される．これはデータセットには含まれない．

Output

各データセットに対して，最低限必要となる車両の台数を 1 行に出力しなさい．

Sample Input

3
05:47:15 09:54:40
12:12:59 12:13:00
16:30:20 21:18:53
6
00:00:00 03:00:00
01:00:00 03:00:00
02:00:00 03:00:00
03:00:00 04:00:00
03:00:00 05:00:00
03:00:00 06:00:00
0

Output for the Sample Input

1
3


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 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
  for _ = 0 to q - 1 do
    Scanf.scanf "%s\n%s\n" (fun x y -> (x, y)) |> lcs |> Printf.printf "%d\n"
  done


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

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


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 f () = List.map int_of_string (split (read_line ()) ' ')

let dfs g n =
  let v = Array.make n (-1) in
  let rec dudu j = function
    | [] -> ()
    | hd :: tl when v.(hd) = (-1) -> (wa hd j; dudu j tl)
    | _ :: tl -> dudu j tl
  and wa i j = v.(i) <- j; dudu j g.(i)
  and doit i =
    if i < n then (if v.(i) = (-1) then wa i i; doit (i + 1))
  in
  doit 0;
  v

let () =
  match f () with
  | [n;m] -> begin
      let g = Array.make n [] in
      let rec read i =
        if i < m then
          match f () with
          | [s;t] -> begin
              g.(s) <- t :: g.(s);
              g.(t) <- s :: g.(t);
              read (i + 1)
            end
          | _ -> exit 1
      in
      read 0;
      let v = dfs g n in
      let q = read_int () in
      let rec read_q i =
        if i < q then begin
          match f () with
          | [s;t] -> begin
              print_endline (if v.(s) = v.(t) then "yes" else "no");
              read_q (i + 1)
            end
          | _ -> exit 1
        end
      in
      read_q 0
    end
  | _ -> exit 1

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


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 ->
      let s1 = sub s 0 i in
      doit s1 (sub s (i + 1) (length s - length s1 - 1) :: acc)
  in doit str []

let read_ints () = List.map int_of_string (split (read_line ()) ' ')

let dfs g n =
  let v = Array.make n (-1) in
  let rec doit i =
    if i < n then (if v.(i) = (-1) then dudu i i; doit (i + 1))
  and dudu i j =
    v.(i) <- j;
    wa j g.(i)
  and wa j = function
    | [] -> ()
    | hd :: tl when v.(hd) = (-1) -> (dudu hd j; wa j tl)
    | _ :: tl -> wa j tl
  in doit 0;
  v

let solve n m =
  let g = Array.make n [] in
  let rec read i =
    if i < m then
      begin match read_ints () with
      | [s;t] ->
        g.(s) <- t :: g.(s);
        g.(t) <- s :: g.(t);
        read (i + 1)
      | _ -> exit 1
      end in
  read 0;
  let v = dfs g n in
  let q = read_int () in
  let rec read_q i =
    if i < q then
      begin match read_ints () with
      | [s;t] ->
        print_endline (if v.(s) = v.(t) then "yes" else "no");
        read_q (i + 1)
      | _ -> exit 1
      end in
  read_q 0

let () =
  match read_ints () with
  | [n;m] -> solve n m
  | _ -> exit 1


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 ret = t.node.(1) in
    t.node.(1) <- t.node.(t.size);
    t.size <- t.size - 1;
    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 begin
        let tmp = t.node.(i) in t.node.(i) <- t.node.(m); t.node.(m) <- tmp;
        max_heapify m
      end in
    max_heapify 1;
    ret

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

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

let dijkstra g n =
  let h = H.make 100000 (0, 0) in
  let d = Array.make n max_int in
  let b = Array.make n false in
  d.(0) <- 0;
  b.(0) <- true;
  H.push (0, 0) h;
  let rec doit () =
    if not (H.empty_p h) then begin
      let (x, u) = H.pop h in
      b.(u) <- true;
      if d.(u) >= (-x) then duduwa u g.(u);
      doit ()
    end
  and duduwa u = function
    | [] -> ()
    | (v, _) :: tl when b.(v) = true -> duduwa u tl
    | (v, c) :: tl when d.(v) <= d.(u) + c -> duduwa u tl
    | (v, c) :: tl ->
      begin
        d.(v) <- d.(u) + c;
        H.push ((-d.(v)), v) h;
        duduwa u tl
      end in
  doit ();
  d

let rec make_pair acc = function
  | [] -> acc
  | f :: t :: tl -> make_pair ((f, t) :: acc) tl
  | _ -> exit 1

let () =
  let n = read_int () in
  let g = Array.make n [] in
  let rec read i =
    if i < n then
      match List.map int_of_string (Str.split (Str.regexp " ") (read_line ())) with
      | u :: _ :: l -> (g.(u) <- make_pair [] l; read (i + 1))
      | _ -> exit 1
  in read 0;
  Array.iteri (fun i e -> Printf.printf "%d %d\n" i e) (dijkstra g n)

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 5000 (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 area =
  [| [1; 3]; [0; 2; 4]; [1; 5]
   ; [0; 4; 6]; [1; 3; 5; 7]; [2; 4; 8]
   ; [3; 7]; [4; 6; 8]; [5; 7] |]

let md = Array.make_matrix 9 9 0

let initialize_md () =
  for i = 0 to 7 do
    for j = 0 to 8 do
      md.(i+1).(j) <- abs (i / 3 - j / 3) + abs (i mod 3 - j mod 3)
    done
  done

let idastar a limit space_i lower goal =
  let rec doit i space_i moved lower =
    if i = limit then begin
      if a = goal then begin
        List.length moved - 1 |> Printf.printf "%d\n"; exit 0
      end;
    end else
      List.iter (fun j ->
        let x = a.(j) in
        if x = List.hd moved then () else
        let lower = lower - md.(x).(j) + md.(x).(space_i) in
        if lower + i > limit then ()
        else begin
          a.(j) <- 0;
          a.(space_i) <- x;
          doit (i + 1) j (x :: moved) lower;
          a.(j) <- x;
          a.(space_i) <- 0;
        end) area.(space_i) in
  doit 0 space_i [-1] lower

let () =
  initialize_md ();
  let a = Array.init 9 (fun _ -> Scanf.scanf "%d " (fun i -> i)) in
  let rec f i =
    if i = 9 then assert false
    else if a.(i) = 0 then i
    else f (i + 1) in
  let space_i = f 0 in
  let rec g i acc =
    if i = 9 then acc
    else g (i + 1) (acc + md.(a.(i)).(i)) in
  let lower = g 0 0 in
  let goal = [|1; 2; 3; 4; 5; 6; 7; 8; 0|] in
  for limit = lower to 31 do
    idastar a limit space_i lower goal;
  done

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

15 Puzzle

The goal of the 15 puzzle problem is to complete pieces on $4 \times 4$ cells where one of the cells is empty space.

In this problem, the space is represented by 0 and pieces are represented by integers from 1 to 15 as shown below.

1 2 3 4
6 7 8 0
5 10 11 12
9 13 14 15

You can move a piece toward the empty space at one step. Your goal is to make the pieces the following configuration in the shortest move (fewest steps).

1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 0

Write a program which reads an initial state of the puzzle and prints the fewest steps to solve the puzzle.

Input

The $4 \times 4$ integers denoting the pieces or space are given.

Output

Print the fewest steps in a line.

Constraints

The given puzzle is solvable in at most 45 steps.

Sample Input

1 2 3 4
6 7 8 0
5 10 11 12
9 13 14 15

Sample Output

8


let (n1, n2) = (4, 16)

let area =
  [| [1; 4]; [0; 2; 5]; [1; 3; 6]; [2; 7]
   ; [0; 5; 8]; [1; 4; 6; 9]; [2; 5; 7; 10]; [3; 6; 11]
   ; [4; 9; 12]; [5; 8; 10; 13]; [6; 9; 11; 14]; [7; 10; 15]
   ; [8; 13]; [9; 12; 14]; [10; 13; 15]; [11; 14] |]

let md = Array.make_matrix n2 n2 0

let initialize_md () =
  for i = 0 to n2 - 2 do
    for j = 0 to n2 - 1 do
      md.(i+1).(j) <- abs (i / n1 - j / n1) + abs (i mod n1 - j mod n1)
    done
  done

let idastar a limit space_i lower goal =
  let rec doit i space_i moved lower =
    if i = limit then begin
      if a = goal then begin
        Printf.printf "%d\n" (List.length moved - 1);
        exit 0;
      end
    end else
      List.iter (fun j ->
        let x = a.(j) in
        if x = List.hd moved then () else
        let lower = lower - md.(x).(j) + md.(x).(space_i) in
        if lower + i > limit then ()
        else
          a.(j) <- 0;
          a.(space_i) <- x;
          doit (i + 1) j (x :: moved) lower;
          a.(j) <- x;
          a.(space_i) <- 0) area.(space_i) in
  doit 0 space_i [-1] lower

let () =
  initialize_md ();
  let a = Array.init n2 (fun _ -> Scanf.scanf "%d " (fun i -> i)) in
  let rec f i =
    if i = n2 then assert false
    else if a.(i) = 0 then i
    else f (i + 1) in
  let space_i = f 0 in
  let rec g i acc =
    if i = n2 then acc
    else g (i + 1) (acc + md.(a.(i)).(i)) in
  let lower = g 0 0 in
  let goal = [|1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 0|] in
  for limit = lower to 45 do
    idastar a limit space_i lower goal
  done


let (n1, n2, n_limit) = (4, 16, 45)

let area =
  [| [1; 4]; [0; 2; 5]; [1; 3; 6]; [2; 7]
   ; [0; 5; 8]; [1; 4; 6; 9]; [2; 5; 7; 10]; [3; 6; 11]
   ; [4; 9; 12]; [5; 8; 10; 13]; [6; 9; 11; 14]; [7; 10; 15]
   ; [8; 13]; [9; 12; 14]; [10; 13; 15]; [11; 14] |]

let goal = Array.init n2 (fun i -> (i + 1) mod n2)

let md = Array.make_matrix n2 n2 0

let initialize_md () =
  for i = 0 to n2 - 2 do
    for j = 0 to n2 - 1 do
      md.(i+1).(j) <- abs (i / n1 - j / n1) + abs (i mod n1 - j mod n1)
    done
  done

let idastar a limit space lower =
  let rec doit i space moved lower =
    if i = limit then begin
      if a = goal then begin
        List.length moved - 1 |> Printf.printf "%d\n";
        exit 0;
      end
    end else
      List.iter (fun j ->
        let x = a.(j) in
        if x = List.hd moved then () else
        let lower = lower - md.(x).(j) + md.(x).(space) in
        if lower + i > limit then ()
        else begin
          a.(j) <- 0;
          a.(space) <- x;
          doit (i + 1) j (x :: moved) lower;
          a.(j) <- x;
          a.(space) <- 0;
        end) area.(space) in
  doit 0 space [-1] lower

let () =
  initialize_md ();
  let a = Array.init n2 (fun _ -> Scanf.scanf "%d " (fun i -> i)) in
  let rec findi i =
    if i = n2 then assert false
    else if a.(i) = 0 then i
    else findi (i + 1) in
  let space = findi 0 in
  let lower =
    Array.fold_left (fun (i, sum) e -> (i + 1, sum + md.(e).(i))) (0, 0) a |> snd in
  for limit = lower to n_limit do
    idastar a limit space lower
  done


let (n1, n2, n_limit) = (4, 16, 45)

let area =
  [| [1; 4]; [0; 2; 5]; [1; 3; 6]; [2; 7]
   ; [0; 5; 8]; [1; 4; 6; 9]; [2; 5; 7; 10]; [3; 6; 11]
   ; [4; 9; 12]; [5; 8; 10; 13]; [6; 9; 11; 14]; [7; 10; 15]
   ; [8; 13]; [9; 12; 14]; [10; 13; 15]; [11; 14] |]

let goal = Array.init n2 (fun i -> (i + 1) mod n2)

let md = Array.make_matrix n2 n2 0

let initialize_md () =
  for i = 0 to n2 - 2 do
    for j = 0 to n2 - 1 do
      md.(i+1).(j) <- abs (i / n1 - j / n1) + abs (i mod n1 - j mod n1)
    done
  done

let idastar a limit space lower =
  let rec doit i space moved lower =
    if i = limit then
      if a <> goal then ()
      else begin
        Printf.printf "%d\n" limit;
        exit 0;
      end
    else
      List.iter (fun j ->
        let x = a.(j) in
        if x = moved then ()
        else
          let lower = lower - md.(x).(j) + md.(x).(space) in
          if lower + i > limit then ()
          else begin
            a.(j) <- 0;
            a.(space) <- x;
            doit (i + 1) j x lower;
            a.(j) <- x;
            a.(space) <- 0;
          end)
      area.(space) in
  doit 0 space (-1) lower

let findi a x =
  let n = Array.length a in
  let rec doit i =
    if i = n then assert false
    else if a.(i) = x then i
    else doit (i + 1) in
  doit 0

let () =
  initialize_md ();
  let a = Array.init n2 (fun _ -> Scanf.scanf "%d " (fun i -> i)) in
  let space = findi a 0 in
  let lower =
    Array.fold_left (fun (i, sum) e -> (i + 1, sum + md.(e).(i))) (0, 0) a |> snd in
  for limit = lower to n_limit do
    idastar a limit space lower
  done


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

type puzzle = { board : int array; space : int; moved: int; lower : int; turn : int }
type ss = { puzzle : puzzle; estimated : int }

module H = MakeBinaryHeap(struct type t = ss let compare x y = y.estimated - x.estimated end)

let (n1, n2) = (4, 16)

let goal = Array.init n2 (fun i -> (i + 1) mod n2)

let area = Array.make n2 []

let md = Array.make_matrix n2 n2 0

let initialize_area () =
  for i = 0 to n2 - 1 do
    let lst = [] in
    let lst = if i + n1 < n2 then (i + n1) :: lst else lst in
    let lst = if (i + 1) mod n1 <> 0 then (i + 1) :: lst else lst in
    let lst = if i - 1 >= 0 && (i - 1) mod n1 <> n1 - 1 then (i - 1) :: lst else lst in
    let lst = if i - n1 >= 0 then (i - n1) :: lst else lst in
    area.(i) <- lst;
  done

let initialize_md () =
  for i = 0 to n2 - 2 do
    for j = 0 to n2 - 1 do
      md.(i+1).(j) <- abs (i / n1 - j / n1) + abs (i mod n1 - j mod n1)
    done
  done

let astar board space lower =
  let reached_p = Hashtbl.create ~random:true 100000 in
  let que = H.make 1000000 { puzzle = { board=[||]; space=0; moved=0; lower=0; turn=0 }; estimated = 0} in
  H.push { puzzle = { board; space; moved=(-1); lower; turn=0 }; estimated = lower } que;
  while not (H.empty_p que) do
    let ss = H.pop que in
    let { puzzle = pzl } = ss in
    if pzl.lower = 0 then begin
      Printf.printf "%d\n" pzl.turn;
      exit 0;
    end else begin
      Hashtbl.add reached_p { board=Array.copy pzl.board; space=pzl.space; moved=pzl.moved; lower=pzl.lower; turn=pzl.turn; } true;
      List.iter (fun j ->
        let x = pzl.board.(j) in
        if x = pzl.moved then ()
        else begin
          let lower = pzl.lower - md.(x).(j) + md.(x).(pzl.space) in
          let board = Array.copy pzl.board in
          board.(j) <- 0;
          board.(pzl.space) <- x;
          if not (Hashtbl.mem reached_p { board; space = j; moved = x; lower; turn=pzl.turn }) then begin
            let pzl = { board; space = j; moved = x; lower; turn = pzl.turn + 1 } in
            H.push { puzzle = pzl; estimated = pzl.turn + pzl.lower } que;
          end;
        end)
      area.(pzl.space);
    end
  done;
  assert false

let findi a x =
  let n = Array.length a in
  let rec doit i =
    if i = n then assert false
    else if a.(i) = x then i
    else doit (i + 1) in
  doit 0

let () =
  initialize_area ();
  initialize_md ();
  let a = Array.init n2 (fun _ -> Scanf.scanf "%d " (fun i -> i)) in
  let space = findi a 0 in
  Array.fold_left (fun (i, sum) e -> (i + 1, sum + md.(e).(i))) (0, 0) a
  |> snd
  |> astar a space


let bm_search x y n m =
  let t = Array.init 256 (fun _ -> m) in
  String.iteri (fun i c -> t.(Char.code c) <- m - 1 - i) y;
  let rec scan i j =
    if x.[i] <> y.[j] then doit (i + max t.(Char.code x.[i]) (m - j))
    else if j = 0 then Some i
    else scan (i - 1) (j - 1)
  and doit i =
    if i >= n then None
    else scan i (m - 1)
  in doit (m - 1)

let () =
  let x = read_line () in
  let y = read_line () in
  let m = String.length y in
  let rec doit i x n =
    if n < m then ()
    else
      match bm_search x y n m with
      | None -> ()
      | Some j ->
        begin
          Printf.printf "%d\n" (i + j);
          let s = String.sub x (j + 1) (n - (j + 1)) in
          doit (i + j + 1) s (String.length s)
        end in
  doit 0 x (String.length x)

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

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 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 () =
  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
      begin match
        try Some (Str.search_forward (Str.regexp p) t sa.(r)) with _ -> None
      with
      | None -> Printf.printf "0\n"
      | _ -> Printf.printf "1\n"
      end;
      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 1000001 0
let tmp = Array.make 1000001 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 rec doit k =
    if k > n then ()
    else begin
      Array.fast_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;
      doit (2 * k)
    end in
  doit 1;
  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 rec doit l r =
      if r - l <= 1 then l
      else
        let m = (l + r) / 2 in
        if range_cmp t n sa.(m) p k <= 0 then doit m r
        else doit l m in
    let l = doit 0 (n + 1) in
    Printf.printf "%d\n" (if range_cmp t n sa.(l) p k = 0 then 1 else 0);
  done


let rec range x y = if x > y then [] else x :: range (x+1) y

let isPrime n =
  if n = 2 then true
  else
    range 2 (n-1)
      |> List.map (fun x -> n mod x = 0)
      |> List.for_all (fun x -> not x)

let () =
  let counter = ref 0 in
  let n = Scanf.scanf "%d\n" (fun x -> x) in
  for i = 1 to n do
    let m = Scanf.scanf "%d\n" (fun x -> x) in
    if isPrime m then counter := !counter + 1 else ();
  done;
  Printf.printf "%d\n" !counter

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 () =
  let n = read_int () in
  let rec loop mv md = function
      0 -> md
    | i ->
      let v = read_int () in
      let d = v - mv in
      loop (if v < mv then v else mv) (if d > md then d else md) (i-1)
  in
  let x = loop (read_int ()) min_int (n-1) in
  Printf.printf "%d\n" x

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 () =
  let n = read_int () in
  let ans = ref min_int in
  let m = ref (read_int ()) in
  for _ = 1 to n - 1 do
    let r = read_int () in
    if !ans < (r - !m) then ans := r - !m;
    if r < !m then m := r;
  done;
  Printf.printf "%d\n" !ans


let () =
  let m = Scanf.scanf "%d\n" (fun x -> x) in
  let minv = ref (Scanf.scanf "%d\n" (fun x -> x)) in
  let n, d = Scanf.scanf "%d\n" (fun x -> x , x - !minv) in
  let maxv = ref d in
  if n < !minv then minv := n else ();
  for i = 1 to m - 2 do
    let num, diff = Scanf.scanf "%d\n" (fun x -> x, x - !minv) in
    if !maxv < diff then maxv := diff else ();
    if num < !minv then minv := num else ();
  done;
  Printf.printf "%d\n" !maxv;;


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 print_result = List.iter (fun (s, t) -> Printf.printf "%s %d\n" s t)

let () =
  match List.map int_of_string (split (read_line ()) ' ') with
  | [] | [_] -> exit 1
  | n :: q :: _ -> begin
      let que = Queue.create () in
      let rec read i =
        if i >= n then ()
        else begin
          match split (read_line ()) ' ' with
          | [] | [_] -> exit 1
          | s :: t :: _ -> (Queue.add (s, int_of_string t) que; read (i + 1))
        end
      in
      read 0;
      let rec doit cnt ret =
        if Queue.is_empty que then List.rev ret
        else begin
          let (s, t) = Queue.take que in
          let rest = t - q in
          if rest > 0 then (Queue.add (s, rest) que; doit (cnt + q) ret)
          else let x = cnt + t in doit x ((s, x) :: ret)
        end
      in
      print_result (doit 0 [])
    end

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 que = create () in
  let (n, q) = Scanf.scanf "%d %d\n" (fun n q -> (n, q)) in
  let rec read i =
    if i < n then (Scanf.scanf "%s %d\n" (fun s t -> add (s, t) que); read (i + 1))
  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 Printf.printf "%s %d\n" s x; doit x)
      else (add (s, rest) que; doit (cnt + q))
    end
  in
  doit 0


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

  let capacity (t: (string * int) t) = t.mask + 1

  let is_empty (t: (string * int) t) = t.length = 0

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

  let enq (t: (string * int) t) (a: string * int) =
    let (elems: (string * int) array) = t.elems in
    elems.(t.index) <- a;
    t.length <- t.length + 1;
    t.index <- (t.index + 1) mod (capacity t)

  let deq (t: (string * int) t) =
    let (elems: (string * int) array) = t.elems in
    let (front: int) = t.front in
    let (res: string * int) = elems.(front) in
    t.front <- (t.front + 1) mod (capacity t);
    t.length <- t.length - 1;
    res
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) = deq q 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


type 'a t = {
  mutable front : int;
  mutable mask  : int;
  mutable index : int;
  mutable length : int;
  mutable elems : (string * int) array
}

let capacity (t: (string * int) t) = t.mask + 1

let is_empty (t: (string * int) t) = t.length = 0

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

let enq (t: (string * int) t) (a: string * int) =
  let (elems: (string * int) array) = t.elems in
  elems.(t.index) <- a;
  t.length <- t.length + 1;
  t.index <- if t.mask=t.index then 0 else t.index + 1

let deq (t: (string * int) t) =
  let (elems: (string * int) array) = t.elems in
  let (front: int) = t.front in
  let (res: string * int) = elems.(front) in
  t.front <- if t.mask=t.front then 0 else t.front+1;
  t.length <- t.length - 1;
  res

let () =
  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) = deq q 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 (que : (string * int) Queue.t) = create () in
  let (n, q) = Scanf.scanf "%d %d\n" (fun n q -> (n, q)) in
  for _ = 0 to n - 1 do
    add (Scanf.scanf "%s %d\n" (fun s t -> (s, t))) que
  done;
  let cnt = ref 0 in
  while not (is_empty que) do
    let (s, t) = take que in
    let rest = t - q in
    if rest > 0 then begin
      add (s, rest) que;
      cnt := !cnt + q;
    end else begin
      let x = !cnt + t in
      Printf.printf "%s %d\n" s x;
      cnt := x;
    end
  done


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


module DLinkedList = struct
  type 'a element =
    { value : 'a;
      mutable next : 'a element option;
      mutable prev : 'a element option
    }
  type 'a t = {
    mutable first : 'a element option;
    mutable last  : 'a element option
  }

  let create () = {first = None; last = None}
  let is_empty t = t.first = None && t.last = None
  let value elt = elt.value
  let next elt = elt.next

  let insert_first t value =
    let new_elt = {prev = None; next = t.first; value} in
    begin match t.first with
      | Some old_first -> old_first.prev <- Some new_elt
      | None -> ()
    end;
    t.first <- Some new_elt;
    begin match t.last with
      | Some _ -> ()
      | None -> t.last <- Some new_elt
    end

  let remove t elt =
    let {prev; next; _} = elt in
    begin match prev with
      | Some prev -> prev.next <- next
      | None -> t.first <- next
    end;
    begin match next with
      | Some next -> next.prev <- prev
      | None -> t.last <- prev
    end;
    elt.prev <- None;
    elt.next <- None

  let find t (v:int) =
    let rec loop = function
      | None -> ()
      | Some elt ->
        if v = (value elt) then remove t elt
        else loop (next elt)
    in
    loop t.first

  let remove_first t =
    begin match t.first with
      | Some first ->
        begin match first.next with
          | Some e -> e.prev <- None; t.first <- first.next
          | None -> t.first <- None; t.last <- None
        end
      | None -> ()
    end

  let remove_last t =
    begin match t.last with
      | Some last ->
        begin match last.prev with
          | Some e -> e.next <- None; t.last <- last.prev
          | None -> t.first <- None; t.last <- None
        end
      | None -> ()
    end

  let iter t ~f =
    let rec loop = function
      | None -> ()
      | Some elt -> f elt; loop (next elt)
    in loop t.first
end

let () =
  let open DLinkedList in
  let (n: int) = read_int () in
  let (dll: int t) = create () in
  for i=1 to n do
    begin match read_line () with
      | "deleteFirst" -> remove_first dll
      | "deleteLast" -> remove_last dll
      | s ->
        begin match String.sub s 0 6,
                    (String.sub s 7 (String.length s - 7)
                     |> int_of_string) with
        | "insert", n -> insert_first dll n
        | "delete", n -> find dll n
        | _ -> ()
        end
    end
  done;
  iter dll
    ~f:(fun e -> match next e with
          Some _ -> Printf.printf "%d " (value e)
        | None -> Printf.printf "%d\n" (value e))

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


open Printf open Scanf
module Lib = struct
  let i32,i64,ist = Int64.(to_int,of_int,to_string)
  let (+$) = (+) let (-$) = (-) let (/$) = (/) let ( *$) = ( * ) let (%$) = (mod)
  let labs = Int64.abs
  let (+),(-),( * ),(/),(mod),(%) = Int64.(add,sub,mul,div,rem,rem)
  let (+=) r v = r := !r + v
  let (-=) r v = r := !r - v
  let ( *= ) r v = r := !r * v
  let (/=) r v = r := !r / v
  let (%=) r v = r := !r % v
  let max_i64,min_i64 = Int64.(max_int,min_int)
  (* math *)
  let ceildiv p q = (p+q-1L) / q
  let rec gcd m n = match m,n with | m,0L -> m | m,n -> gcd n (m mod n)
  let lcm m n = m / gcd m n * n
  module I64_infix = struct
    let (land),(lor),(lxor),lnot,(lsl),(lsr),(asr) =
      let open Int64 in
      (logand),(logor),(logxor),lognot,
      (fun u v -> shift_left u (i32 v)),
      (fun u v -> shift_right u (i32 v)),
      (fun u v -> shift_right_logical u (i32 v))
  end
  (* input *)
  let input_i64_array n = Array.init (i32 n) (fun _ -> Scanf.scanf " %Ld" (fun v -> v))
  let get_i64 _ = Scanf.scanf " %Ld" (fun v -> v)
  let get_2_i64 _ = Scanf.scanf " %Ld %Ld" (fun u v -> u,v)
  let get_3_i64 _ = Scanf.scanf " %Ld %Ld %Ld" (fun u v w -> u,v,w)
  let get_4_i64 _ = Scanf.scanf " %Ld %Ld %Ld %Ld" (fun u v w x -> u,v,w,x)
  let get_5_i64 _ = Scanf.scanf " %Ld %Ld %Ld %Ld %Ld" (fun u v w x y -> u,v,w,x,y)
  let i32_get_int _ = Scanf.scanf " %d" (fun v -> v) let i32_get_2_ints _ = Scanf.scanf " %d %d" (fun u v -> u,v) let i32_get_3_ints _ = Scanf.scanf " %d %d %d" (fun u v w -> u,v,w) let i32_get_4_ints _ = Scanf.scanf " %d %d %d %d" (fun u v w x -> u,v,w,x) let i32_get_5_ints _ = Scanf.scanf " %d %d %d %d %d" (fun u v w x y -> u,v,w,x,y)
  (* utils *)
  external id : 'a -> 'a = "%identity"
  let ( *< ) f g x = f (g x)
  let ( *> ) f g x = g (f x)
  let rv f p q = f q p (* ex. 24 |> rv (/) 6 *)
  let alen a = i64 @@ Array.length a
  let llen l = i64 @@  List.length l
  let string_of_list ?(separator=" ") f ls = ls |> List.map f |> String.concat separator
  let string_of_array ?(separator=" ") f a = a |> Array.to_list |> string_of_list ~separator f
  let char_list_of_string str = let rec f0 i a = if i<0 then a else f0 (i-$1) (str.[i]::a) in f0 (String.length str -$ 1) []
  let string_of_char_list ls = List.fold_left (fun u v -> u ^ (String.make 1 v)) "" ls
  let fail _ = failwith "fail"
  let dx,dy = [|1;0;-1;0|],[|0;1;0;-1|]
  let range l r = let ls = ref [] in for i=i32 l to i32 r do ls := i :: !ls done;!ls |> List.rev
  let cartesian_product u v = u |> List.map (fun p -> List.map (fun q -> p,q) v) |> List.flatten
  let shuffle a = Array.sort (fun _ _ -> (Random.int 3) -$ 1) a
  let binary_search ng ok f = let d = if ng < ok then 1L else -1L in
    let rec f0 ng ok =
      if labs (ok - ng) <= 1L then ok
      else let mid = ng + (ok - ng) / 2L in if f mid then f0 ng mid else f0 mid ok
    in f0 (ng-1L*d) (ok+1L*d)
  let lower_bound a v = binary_search 0L (alen a - 1L) (fun i -> a.(i32 i) >= v)
  let upper_bound a v = binary_search 0L (alen a - 1L) (fun i -> a.(i32 i) >  v)
  let equal_range a v = lower_bound a v, upper_bound a v (* #=snd-fst *)
  let rec fix f x = f (fix f) x
  let fix_memo ?(size=10000) f x =
    let tb = Hashtbl.create ~random:true size in
    let rec f0 x =
      try Hashtbl.find tb x with
      | Not_found -> (let v = f f0 x in Hashtbl.add tb x v; v)
    in f0 x
  (* imperative *)
  let rep f t ?(stride=1L) fbod = let i = ref f in while !i <= t do fbod !i; i := !i + stride done
  let repb f t ?(stride=1L) fbod = let i,c = ref f,ref true in while !i <= t && !c do
    match fbod !i with | `Break -> c := false | `Ok -> i := !i + stride done
  let repm f t ?(stride=1L) m0 fbod =
    let i,c,m = ref f,ref true,ref m0 in
    while !i<=t && !c do match fbod !m !i with
    | `Break -> c := false | `Break_m m' -> (c := false; m := m') | `Ok m' -> m := m'; i := !i + stride done; !m
  let repi f t ?(stride=1) fbod = let i = ref f in while !i <= t do fbod !i; i := !i +$ stride done
  let repib f t ?(stride=1) fbod = let i,c = ref f,ref true in while !i <= t && !c do
    match fbod !i with | `Break -> c := false | `Ok -> i := !i +$ stride done
  let repim f t ?(stride=1) m0 fbod =
    let i,c,m = ref f,ref true,ref m0 in
    while !i<=t && !c do match fbod !m !i with
    | `Break -> c := false | `Break_m m' -> (c := false; m := m') | `Ok m' -> m := m'; i := !i +$ stride done; !m
  let rep_rev f t ?(stride=1L) fbod = rep t f ~stride @@ fun v -> fbod @@ f + t - v
  let repb_rev f t ?(stride=1L) fbod = repb t f ~stride @@ fun v -> fbod @@ f + t - v
  let repm_rev f t ?(stride=1L) m0 fbod = repm f t ~stride m0 @@ fun u v -> fbod u @@ f + t - v
  let repi_rev f t ?(stride=1) fbod = repi t f ~stride @@ fun v -> fbod @@ f +$ t -$ v
  let repib_rev f t ?(stride=1) fbod = repib t f ~stride @@ fun v -> fbod @@ f +$ t -$ v
  let repim_rev f t ?(stride=1) m0 fbod = repim f t ~stride m0 @@ fun u v -> fbod u @@ f +$ t -$ v
  (* output *)
  let print_list_mle f ls = string_of_list f ls |> print_endline
  let print_array_mle f a = string_of_array f a |> print_endline
  let print_list f ls = ls |> List.iter (fun v -> printf "%s " @@ f v); print_newline ()
  let print_array f a = a |> Array.iter (fun v -> printf "%s " @@ f v); print_newline ()
  (* debug *)
  let dump_2darr f a = a |> Array.iter (fun b -> print_array f b)
  let dump_i64_list ls = print_list ist ls
  let dump_i64_array a = print_array ist a
end open Lib open Array

module Deque = struct
  (* let (+$),(-$) = Pervasives.((+),(-)) *)
  type 'a u = {
    mutable prev: 'a cell;
    value: 'a;
    mutable next: 'a cell; }
  and 'a cell = Nil | Cons of 'a u
  type 'a t = {
    mutable length: int;
    mutable head: 'a cell;
    mutable tail: 'a cell; }
  exception Empty
  let empty () = {length=0;head=Nil;tail=Nil}
  let is_empty {length;_} = length=0
  let length {length;_} = length
  let clear q = q.length <- 0; q.head <- Nil; q.tail <- Nil
  let push_rear value q = match q.tail with
  | Nil ->
    let n = Cons {prev=Nil; value; next=Nil} in
    q.length <- 1; q.head <- n; q.tail <- n
  | Cons tail ->
    let n = Cons {prev=q.tail; value; next=Nil} in
    q.length <- q.length+$1; tail.next <- n; q.tail <- n
  let pop_front q = match q.head with
  | Nil -> raise Empty
  | Cons {value;next=Nil;_} -> clear q; value
  | Cons {value;next=Cons c as next;_} ->
    q.length <- q.length-$1; c.prev <- Nil; q.head <- next; value
  let push_front value q = match q.head with
  | Nil ->
    let n = Cons {prev=Nil; value; next=Nil} in
    q.length <- 1; q.head <- n; q.tail <- n
  | Cons head ->
    let n = Cons {prev=Nil; value; next=q.head} in
    q.length <- q.length+$1; head.prev <- n; q.head <- n
  let pop_rear q = match q.tail with
  | Nil -> raise Empty
  | Cons {value;prev=Nil;_} -> clear q; value
  | Cons {value;prev=Cons c as prev;_} ->
    q.length <- q.length-$1; c.next <- Nil; q.tail <- prev; value
  let front q = match q.head with
  | Nil -> raise Empty
  | Cons {value;_} -> value
  let rear q = match q.tail with
  | Nil -> raise Empty
  | Cons {value;_} -> value
  let iter f {head;_} =
    let rec f0 = function | Nil -> () | Cons {value;next;_} -> f value; f0 next
    in f0 head
  let iter_rev f {tail;_} =
    let rec f0 = function | Nil -> () | Cons {value;prev;_} -> f value; f0 prev
    in f0 tail
  let fold f u0 {head;_} =
    let rec f0 u = function | Nil -> u | Cons {value;next;_} -> f0 (f u value) next
    in f0 u0 head
  let of_list ls =
    let q = empty () in List.iter (fun v -> push_rear v q) ls; q
  let to_list q = fold (fun u v -> v::u) [] q |> List.rev
end

let () =
  let n = get_i64 0 in
  let q = Deque.empty () in
  rep 1L n (fun _ ->
    match scanf " %s" @@ id with
    | "insert" -> (
      let v = get_i64 0 in
      Deque.push_front v q
    )
    | "delete" -> (
      let w = get_i64 0 in
      let ls = Deque.fold (fun (f,ls) v ->
        if not f && v=w then (true,ls)
        else (f,v::ls)
      ) (false,[]) q |> snd in
      Deque.clear q;
      List.iter (fun v -> Deque.push_front v q) ls
    )
    | "deleteFirst" -> Deque.pop_front q |> ignore
    | "deleteLast" -> Deque.pop_rear q |> ignore
    | _ -> fail 0
  );
  Deque.to_list q |> List.map ist |> String.concat " " |> print_endline


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 = function
      []  -> acc
    | [x] -> x::acc
    | ((s1,e1),v1)::((s2,e2),v2)::r when s1 < s2 && e1 > e2 ->
      loop acc (((s1,e1), v1+v2)::r)
    | a::(b::r as rest) -> loop (a::acc) rest
  in loop [] lst

let () =
  let line = read_line () in
  let count = ref 0 in
  let buf = Buffer.create 128 in
  analysis line |> summarize
  |> List.fold_left
    (fun acc (_,v) ->
       incr count;
       Buffer.add_string buf (Printf.sprintf " %d" v);
       acc+v)
    0
  |> (fun sum -> Printf.printf "%d\n%d%s\n" sum !count (Buffer.contents buf))

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 words str = Str.split (Str.regexp " ") str |> List.map int_of_string

let bs elem (a: int array) =
  let rec loop (i_min,i_max) =
    match i_min > i_max || i_max < i_min with
      true -> false
    | false ->
      let mid = (i_min+i_max)/2 in
      match a.(mid) = elem with
        true -> true
      | false ->
        loop (match a.(mid) < elem with true -> mid+1,i_max | false -> i_min,mid-1)
  in loop (0,(Array.length a) -1)

let () =
  let _ = read_int () in
  let s = read_line () |> words |> Array.of_list in
  let _ = read_int () in
  let t = read_line () |> words in
  List.fold_left (fun acc x -> match bs x s with true -> acc+1 | false -> acc)
    0 t
  |> Printf.printf "%d\n"

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


let bin_search x (a : int array) n =
  let l = ref 0 in
  let r = ref n in
  try
    while !l < !r do
      let m = (!l + !r) / 2 in
      if x = a.(m) then raise Exit;
      if x < a.(m) then r := m
      else l := m + 1;
    done;
    false
  with Exit -> true

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


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 solve n k =
  let a = Array.init n (fun _ -> read_int ()) in
  let rec check = function
    | (i, _, _, _) when i = n -> n
    | (i, j, _, _) when j >= k -> i
    | (i, j, s, p) when s + a.(i) <= p -> check (i + 1, j, s + a.(i), p)
    | (i, j, _, p) -> check (i, j + 1, 0, p) in
  let rec bin_search l r =
    if r < l then l
    else
      let m = (l + r) / 2 in
      if check (0, 0, 0, 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 () =
  match List.map int_of_string (split (read_line ()) ' ') with
  | [n; k] -> solve n k
  | _ -> exit 1

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 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 ()) in
  let l = Array.fold_left (fun x y->max x y) 0 ws 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)
;;


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;
  Array.iteri (fun i e -> if i <> 0 then print_string " "; print_int e) a;
  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 ni = m - l in
  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 ni l in
  let aj = init_ary (r - m) m in
  let rec doit i j k =
    if k < r then begin
      if ai.(i) <= aj.(j) then (a.(k) <- ai.(i); doit (i + 1) j (k + 1))
      else (a.(k) <- aj.(j); cnt := !cnt + (ni - i); 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;
  Printf.printf "%d\n" !cnt

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

The Number of Inversions

For a given sequence $A = \{a_0, a_1, ... a_{n-1}\}$, the number of pairs $(i, j)$ where $a_i > a_j$ and $i < j$, is called the number of inversions. The number of inversions is equal to the number of swaps of Bubble Sort defined in the following program:

bubbleSort(A)
cnt = 0 // the number of inversions
for i = 0 to A.length-1
for j = A.length-1 downto i+1
if A[j] < A[j-1]
swap(A[j], A[j-1])
cnt++

return cnt

For the given sequence $A$, print the number of inversions of $A$. Note that you should not use the above program, which brings Time Limit Exceeded.

Input

In the first line, an integer $n$, the number of elements in $A$, is given. In the second line, the elements $a_i$ ($i = 0, 1, .. n-1$) are given separated by space characters.

output

Print the number of inversions in a line.

Constraints

$ 1 \leq n \leq 200,000$

$ 0 \leq a_i \leq 10^9$

$a_i$ are all different

Sample Input 1

5
3 5 2 1 4

Sample Output 1

6

Sample Input 2

3
3 1 2

Sample Output 2

2


let print_ary a =
  Array.iteri (fun i e -> Printf.printf (if i = 0 then "%d" else " %d") e) a;
  print_newline ()

let rev_iter f a =
  let rec doit i =
    if i >= 0 then (f (Array.get a i); doit (i - 1))
  in
  doit (Array.length a - 1)

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 () else 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 k = Array.fold_left max (-1) a in
  let b = Array.make n 0 in
  counting_sort a b k;
  print_ary b

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 rev_iter (f : int -> unit) (a : int array) =
  let rec doit i =
    if i >= 0 then (f a.(i); doit (i - 1))
  in
  doit (Array.length a - 1)

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


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;
  for i = Array.length a - 1 downto 0 do
    b.(c.( a.(i) ) - 1) <- a.(i);
    c.( a.(i) ) <- c.( a.(i) ) - 1;
  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;
  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 b.(c.(a.(i))-1)<-a.(i);c.(a.(i))<-c.(a.(i))-1;done;print_int b.(0);for i=1to n-1do 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 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 e -> e)) 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