Submission #3044278


Source Code Expand

module SegTree = struct
  module type Monoid = sig
    type t
    val e : t
    val op : t -> t -> t
  end

  module Make (S : Monoid) : sig
    type t
    type elt
    (* n要素の単位元からなるセグ木を作る *)
    val make : int -> t
    (* 
     * update i f t
     * i番目の要素にfを適用したセグ木を作る
     *)
    val update : int -> (elt -> elt) -> t -> t
    (*
     * update_range l r f t
     * [l, r)の要素に自己準同型写像fを適用したセグ木を作る
     *)
    val update_range : int -> int -> (elt -> elt) -> t -> t
    (*
     * query l r t
     * [l, r)の要素の積を求める
     *)
    val query : int -> int -> t -> elt
  end with type elt = S.t = struct
    type elt = S.t
    (* sizeがセグ木の要素数,dataは要素すべてをモノイドの演算で畳み込んだもの *)
    type t = { size : int; data : elt; body : body lazy_t }
    and body = Leaf | Node of t * t

    let make_node left right =
      { size = left.size + right.size;
        data = S.op left.data right.data;
        body = lazy (Node (left, right)) }

    let rec make n = 
      assert (1 <= n);
      { size = n;
        data = S.e;
        body = lazy
          begin match n with
          | 1 -> Leaf
          | n -> Node (make (n / 2), make ((n + 1) / 2))
          end }

    let rec update i f t =
      assert (0 <= i && i < t.size);
      match t with
      | { body = lazy Leaf } -> { t with data = f t.data }
      | { body = lazy (Node (left, right)) } ->
          if i < left.size then make_node (update i f left) right
          else make_node left (update (i - left.size) f right)

    let rec update_range l r f t =
      assert (0 <= l && l < r && r <= t.size);
      match t with
      | { body = lazy Leaf } -> { t with data = f t.data }
      | { body = lazy (Node (left, right)) } ->
          if l <= 0 && t.size <= r then
            { t with
              data = f t.data;
              body = lazy
                (Node
                  (update_range 0 left.size f left,
                   update_range 0 right.size f right)) }
          else if r <= left.size then
            make_node (update_range l r f left) right
          else if left.size <= l then
            make_node left (update_range (l - left.size) (r - left.size) f right)
          else
            make_node
              (update_range l left.size f left)
              (update_range 0 (r - left.size) f right)

    let rec query l r t =
      assert (0 <= l && l < r && r <= t.size);
      match t with
      | { body = lazy Leaf } -> t.data
      | { body = lazy (Node (left, right)) } ->
          if l <= 0 && t.size <= r then t.data
          else if r <= left.size then query l r left
          else if left.size <= l then query (l - left.size) (r - left.size) right
          else S.op (query l left.size left) (query 0 (r - left.size) right)
  end
end

module MinSegTree = SegTree.Make (struct
  type t = int64 * int
  let e = (Int64.max_int, 0)
  let op = min
end)

let () = Scanf.scanf "%d %d\n" @@ fun n k ->
  let abs = Array.init n @@ fun _ ->
    Scanf.scanf "%d %d\n" @@ fun a b ->
      Int64.of_int a, Int64.of_int b in
  Array.fold_left (fun (i, t) (a, _) ->
    (i + 1, MinSegTree.update i (fun _ -> (a, i)) t)) (0, MinSegTree.make n) abs
  |> snd
  |> (fun t -> (0L, t))
  |> Array.fold_right (fun () (acc, t) ->
    let (m, i) = MinSegTree.query 0 n t in
    (Int64.add acc m, MinSegTree.update i (fun (x, i) -> (Int64.add x (snd abs.(i)), i)) t)) (Array.make k ())
  |> fst
  |> Printf.printf "%Ld\n"

Submission Info

Submission Time
Task C - Factory
User fetburner
Language OCaml (4.02.3)
Score 300
Code Size 3687 Byte
Status AC
Exec Time 808 ms
Memory 51584 KB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 300 / 300
Status
AC × 3
AC × 21
Set Name Test Cases
Sample sample_01.txt, sample_02.txt, sample_03.txt
All sample_01.txt, sample_02.txt, sample_03.txt, subtask_1_1.txt, subtask_1_10.txt, subtask_1_11.txt, subtask_1_12.txt, subtask_1_13.txt, subtask_1_14.txt, subtask_1_15.txt, subtask_1_16.txt, subtask_1_17.txt, subtask_1_18.txt, subtask_1_2.txt, subtask_1_3.txt, subtask_1_4.txt, subtask_1_5.txt, subtask_1_6.txt, subtask_1_7.txt, subtask_1_8.txt, subtask_1_9.txt
Case Name Status Exec Time Memory
sample_01.txt AC 1 ms 384 KB
sample_02.txt AC 37 ms 5248 KB
sample_03.txt AC 4 ms 3328 KB
subtask_1_1.txt AC 2 ms 1408 KB
subtask_1_10.txt AC 265 ms 18688 KB
subtask_1_11.txt AC 1 ms 384 KB
subtask_1_12.txt AC 264 ms 30848 KB
subtask_1_13.txt AC 1 ms 384 KB
subtask_1_14.txt AC 165 ms 18688 KB
subtask_1_15.txt AC 808 ms 51584 KB
subtask_1_16.txt AC 13 ms 5120 KB
subtask_1_17.txt AC 5 ms 3328 KB
subtask_1_18.txt AC 461 ms 45052 KB
subtask_1_2.txt AC 219 ms 9600 KB
subtask_1_3.txt AC 130 ms 15488 KB
subtask_1_4.txt AC 108 ms 6400 KB
subtask_1_5.txt AC 276 ms 30976 KB
subtask_1_6.txt AC 153 ms 7168 KB
subtask_1_7.txt AC 50 ms 5376 KB
subtask_1_8.txt AC 713 ms 51580 KB
subtask_1_9.txt AC 642 ms 45180 KB