前提
Haskellで競技プログラミングの問題を解いています。
実現したいこと
リストのk番目の要素を削除する素早い方法を教えてもらいたいです。
発生している問題
TLEとなってしまいます。
おそらくリストのk番目の要素を削除する処理(deleteKの部分)で遅くなっていると思うので、このような質問をいたしました。
問題は
https://atcoder.jp/contests/abc125/tasks/abc125_c
です。
該当のソースコード
haskell
1import Control.Monad 2import qualified Data.ByteString.Char8 as BS 3 4main = do 5 n <- getLine 6 --list <- map read . words <$> getLine 7 list <- map (read . BS.unpack).BS.words <$> BS.getLine 8 print $ result list 9 10 11allGCD list = foldr gcd (head list ) list 12 13deleteK k list = (take k list) ++ (drop (k+1) list ) 14 15deleteRe list = map (\pair -> deleteK (fst pair) list) ziped 16 where ziped = zip [0,1 ..] list 17 18 19resultList list = map allGCD tmpList 20 where tmpList = deleteRe list 21 22result list = maximum $ resultList list
よろしくお願いいたします。
遅い原因が deleteK だけではないので、別の方法を探したほうが良いです。
例えば、resultList list の計算量を考えると(tmpList の作成の計算量はとりあえず無視)、
tmpListの各要素が長さ n-1 のリストなので、それぞれの allGCD を求めるのに n-1 回の計算が必要、
tmpList の長さが n なので、ここだけで n * (n-1) で O(n^2)の時間がかかります。
どうしても高速化する方法を思いつかないなら、解説に頼りましょう。
Haskellでやるなら、解説に書いてある累積和を使う方法が良いかと思います。(というかHaskellでセグメントツリーを使う方法を私が知らないので他に選択肢が無かった)
https://blog.hamayanhamayan.com/entry/2019/04/28/085936
回答していただきありがとうございます!
無事解決いたしました。
回答1件
あなたの回答
tips
プレビュー