結果

問題 No.875 Range Mindex Query
ユーザー guriceringuricerin
提出日時 2020-01-29 16:06:16
言語 F#
(F# 4.0)
結果
WA  
実行時間 -
コード長 5,734 bytes
コンパイル時間 12,442 ms
コンパイル使用メモリ 213,528 KB
実行使用メモリ 77,184 KB
最終ジャッジ日時 2024-09-16 01:06:38
合計ジャッジ時間 23,171 ms
ジャッジサーバーID
(参考情報)
judge4 / judge6
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 63 ms
29,824 KB
testcase_01 WA -
testcase_02 WA -
testcase_03 WA -
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 WA -
testcase_08 WA -
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
権限があれば一括ダウンロードができます
コンパイルメッセージ
  復元対象のプロジェクトを決定しています...
  /home/judge/data/code/main.fsproj を復元しました (628 ms)。
MSBuild のバージョン 17.9.6+a4ecab324 (.NET)
/home/judge/data/code/Main.fs(163,13): warning FS0025: この式のパターン マッチが不完全です たとえば、値 '[|_; _; _; _|]' はパターンに含まれないケースを示す可能性があります。 [/home/judge/data/code/main.fsproj]
/home/judge/data/code/Main.fs(150,9): warning FS0025: この式のパターン マッチが不完全です たとえば、値 '[|_; _; _|]' はパターンに含まれないケースを示す可能性があります。 [/home/judge/data/code/main.fsproj]
  main -> /home/judge/data/code/bin/Release/net8.0/main.dll
  main -> /home/judge/data/code/bin/Release/net8.0/publish/

ソースコード

diff #

open System
open System.Collections.Generic

[<AutoOpen>]
module Cin =
    let read f = stdin.ReadLine() |> f
    let reada f = stdin.ReadLine().Split() |> Array.map f
    let readChars() = read string |> Seq.toArray
    let readInts() = readChars() |> Array.map (fun x -> Convert.ToInt32(x.ToString()))

[<AutoOpen>]
module Cout =
    let writer = new IO.StreamWriter(new IO.BufferedStream(Console.OpenStandardOutput()))
    let print (s: string) = writer.Write s
    let println (s: string) = writer.WriteLine s
    let inline puts (s: ^a) = string s |> println

type LazySegTree<'Monoid, 'OpMonoid> =
    {
      /// 実データの要素数
      size: int
      /// 木の高さ
      height: int
      /// モノイドの単位元
      mUnity: 'Monoid
      /// 作用素の単位元
      omUnity: 'OpMonoid
      nodes: 'Monoid array
      lazyNodes: 'OpMonoid array
      f: F<'Monoid>
      g: G<'Monoid, 'OpMonoid>
      h: H<'OpMonoid> }

and F<'Monoid> = 'Monoid -> 'Monoid -> 'Monoid

and G<'Monoid, 'OpMonoid> = 'Monoid -> 'OpMonoid -> 'Monoid

and H<'OpMonoid> = 'OpMonoid -> 'OpMonoid -> 'OpMonoid

[<RequireQualifiedAccess>]
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module LazySegTree =
    let internal sizeAndHeight n =
        let rec loop sAcc hAcc =
            if sAcc < n then loop (sAcc <<< 1) (hAcc + 1) else (sAcc, hAcc)
        loop 1 0

    let internal parent i = (i - 1) / 2
    let internal leftChild i = (i <<< 1) + 0
    let internal rightChild i = (i <<< 1) + 1
    let internal leafIdx tree k = k + tree.size

    let init (n: int) f g h (mUnity: 'Monoid) (omUnity: 'OpMonoid): LazySegTree<_, _> =
        let size, height = sizeAndHeight n
        let nodes = Array.init (size * 2) (fun _ -> mUnity)
        let lazyNodes = Array.init (size * 2) (fun _ -> omUnity)
        { LazySegTree.size = size
          height = height
          mUnity = mUnity
          omUnity = omUnity
          nodes = nodes
          lazyNodes = lazyNodes
          f = f
          g = g
          h = h }

    /// k番目(0-indexed)の要素をxに更新
    let set (k: int) x tree: unit =
        let size = tree.size
        let idx = leafIdx tree k
        tree.nodes.[idx] <- x

    /// k番目のノードについて遅延評価を行う
    let internal apply (k: int) tree =
        let nodes, lazyNodes = tree.nodes, tree.lazyNodes
        let omUnity = tree.omUnity
        let g = tree.g
        match lazyNodes.[k] = omUnity with
        | true -> nodes.[k]
        | false -> g nodes.[k] lazyNodes.[k]

    /// 親から子への遅延伝播
    let internal propagate (k: int) tree: unit =
        let nodes, lazyNodes = tree.nodes, tree.lazyNodes
        let omUnity = tree.omUnity
        let lc, rc = leftChild k, rightChild k
        let h = tree.h
        let g = tree.g
        if lazyNodes.[k] <> omUnity then
            if k < tree.size then
                lazyNodes.[lc] <- h lazyNodes.[lc] lazyNodes.[k]
                lazyNodes.[rc] <- h lazyNodes.[rc] lazyNodes.[k]
            // nodes.[k] <- apply k tree
            nodes.[k] <- g nodes.[k] lazyNodes.[k]
            lazyNodes.[k] <- omUnity

    let rec internal updateCore a b (x: 'OpMonoid) k l r tree =
        propagate k tree
        let nodes = tree.nodes
        let lazyNodes = tree.lazyNodes
        let f = tree.f
        let h = tree.h
        if r <= a || b <= l then
            nodes.[k]
        elif a <= l && r <= b then
            lazyNodes.[k] <- h lazyNodes.[k] x
            propagate k tree
            nodes.[k]
        else
            let lc, rc, mid = leftChild k, rightChild k, (l + r) >>> 1
            let lm = updateCore a b x lc l mid tree
            let rm = updateCore a b x rc mid r tree
            nodes.[k] <- f lm rm
            nodes.[k]

    /// 半開区間[l, r)を更新する
    let update (l: int) (r: int) (x: 'OpMonoid) (tree: LazySegTree<'Monoid, 'OpMonoid>): 'Monoid =
        updateCore l r x 1 0 tree.size tree

    let rec internal queryCore (a: int) (b: int) (k: int) (l: int) (r: int) tree: 'Monoid =
        propagate k tree
        let mUnity = tree.mUnity
        let f = tree.f
        if r <= a || b <= l then
            mUnity
        elif a <= l && r <= b then
            tree.nodes.[k]
        else
            let lc, rc, mid = leftChild k, rightChild k, (l + r) >>> 1

            let lm = queryCore a b lc l mid tree
            let rm = queryCore a b rc mid r tree
            f lm rm

    /// 半開区間[l, r)の演算結果
    let query (l: int) (r: int) tree: 'Monoid = queryCore l r 1 0 tree.size tree

    /// k番目の要素を取得
    let get (k: int) tree = query k (k + 1) tree

    let dump tree =
        let size = tree.size
        let nodes = tree.nodes.[0..size - 1]
        let mutable buf = ""
        for a in nodes do
            buf <- sprintf "%s%A " buf a
        buf

let main() =
    let [| N; Q |] = reada int
    let A = reada int64

    let f (x: int * int64) (y: int * int64) =
        let xi, xv = x
        let yi, yv = y
        if xi < yi then x else y

    let e = Int32.MaxValue, Int64.MaxValue
    let seg = LazySegTree.init N f f f e e
    for i in 0 .. N - 1 do
        seg |> LazySegTree.set i (i, A.[i])
    for _ in 0 .. Q - 1 do
        let [| q; l; r |] = reada int
        match q with
        | 1 ->
            let l, r = l - 1, r - 1
            let lv = seg |> LazySegTree.get l
            let rv = seg |> LazySegTree.get r
            seg |> LazySegTree.set l rv
            seg |> LazySegTree.set r lv
        | 2 ->
            let (i, _) = seg |> LazySegTree.query l (r + 1)
            puts (i + 1)
        | _ -> failwithf "unreachable"
    ()

main()
writer.Close()
0