Guest User

Untitled

a guest
Nov 18th, 2017
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.43 KB | None | 0 0
  1. let rec fold_tournament dir f = function
  2. | [x] -> x
  3. | xs ->
  4. List.fold_left (fun (acc, prev) x ->
  5. match prev with
  6. | None -> (acc, Some x)
  7. | Some y -> ((if dir then f y x else f x y) :: acc, None)) ([], None) xs
  8. |> (function
  9. | (acc, None) -> acc
  10. | (acc, Some x) -> x :: acc)
  11. |> fold_tournament (not dir) f
  12. (* fold_tournament ( * ) [x1; x2; x3; x4; x5; x6; x7; x8 ... ] = (... (((x1 * x2) * (x3 * x4)) * ((x5 * x6) * (x7 * x8))) ...) * ( ... ) *)
  13. let fold_tournament f xs = fold_tournament true f xs
  14.  
  15. module type SemiGroup = sig
  16. type t
  17. val op : t -> t -> t
  18. end
  19.  
  20. module Make (S : SemiGroup) : sig
  21. type t
  22. type elt
  23. (* リストからセグ木を作る *)
  24. val of_list : elt list -> t
  25. (*
  26. * update i x t
  27. * i番目の要素をxに変更したセグ木を作る
  28. *)
  29. val update : int -> elt -> t -> t
  30. (*
  31. * find l r t
  32. * [l, r)の要素の積を求める
  33. *)
  34. val find : int -> int -> t -> elt
  35. end with type elt = S.t = struct
  36. type elt = S.t
  37. type t =
  38. | Leaf of elt
  39. | Node of { size : int; product : elt; left : t ; right : t }
  40.  
  41. (* セグ木の要素数 *)
  42. let size = function
  43. | Leaf _ -> 1
  44. | Node { size } -> size
  45.  
  46. (* セグ木の持っている要素全ての積 *)
  47. let product = function
  48. | Leaf product
  49. | Node { product } -> product
  50.  
  51. let of_list l =
  52. fold_tournament (fun left right ->
  53. Node
  54. { size = size left + size right;
  55. product = S.op (product left) (product right);
  56. left; right }) (List.map (fun x -> Leaf x) l)
  57.  
  58. let rec update i x t =
  59. assert (0 <= i && i < size t);
  60. match t with
  61. | Leaf _ -> Leaf x
  62. | Node ({ left; right } as record) ->
  63. if i < size left then
  64. let left' = update i x left in
  65. Node { record with
  66. product = S.op (product left') (product right);
  67. left = left' }
  68. else
  69. let right' = update (i - size left) x right in
  70. Node { record with
  71. product = S.op (product left) (product right');
  72. right = right' }
  73.  
  74. let rec find l r t =
  75. assert (0 <= l && l < r && r <= size t);
  76. match t with
  77. | Leaf x -> x
  78. | Node { left; right } ->
  79. if l = 0 && r = size t - 1 then product t
  80. else if r <= size left then find l r left
  81. else if size left <= l then find (l - size left) (r - size left) right
  82. else S.op (find l (size left) left) (find 0 (r - size left) right)
  83. end
Add Comment
Please, Sign In to add comment