結果

問題 No.556 仁義なきサルたち
ユーザー こまるこまる
提出日時 2020-10-16 04:58:47
言語 Haskell
(9.8.2)
結果
WA  
実行時間 -
コード長 2,309 bytes
コンパイル時間 2,923 ms
コンパイル使用メモリ 215,480 KB
実行使用メモリ 8,192 KB
最終ジャッジ日時 2024-07-20 20:17:02
合計ジャッジ時間 5,319 ms
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 WA -
testcase_01 WA -
testcase_02 WA -
testcase_03 WA -
testcase_04 WA -
testcase_05 RE -
testcase_06 RE -
testcase_07 RE -
testcase_08 RE -
testcase_09 WA -
testcase_10 RE -
testcase_11 RE -
testcase_12 RE -
testcase_13 WA -
testcase_14 RE -
testcase_15 RE -
testcase_16 WA -
testcase_17 RE -
testcase_18 RE -
testcase_19 RE -
testcase_20 RE -
testcase_21 RE -
権限があれば一括ダウンロードができます
コンパイルメッセージ
Loaded package environment from /home/judge/.ghc/x86_64-linux-9.8.2/environments/default
[1 of 2] Compiling Main             ( Main.hs, Main.o )
[2 of 2] Linking a.out

ソースコード

diff #

{-# LANGUAGE BangPatterns #-}

import           Control.Arrow
import           Control.Monad
import           Control.Monad.Fix
import           Control.Monad.State
import qualified Data.ByteString.Char8             as BSC8
import qualified Data.Vector.Fusion.Stream.Monadic as VFSM
import qualified Data.Vector.Unboxed               as VU
import qualified Data.Vector.Unboxed.Mutable       as VUM

type Parser a = BSC8.ByteString -> Maybe (a, BSC8.ByteString)
parseInt :: Parser Int
parseInt = fmap (second BSC8.tail) . BSC8.readInt
parse2 :: IO (Int, Int)
parse2 = (\vec -> ((vec VU.! 0) - 1, (vec VU.! 1) - 1)) . VU.unfoldrN 2 parseInt <$> BSC8.getLine

stream :: Monad m => Int -> Int -> VFSM.Stream m Int
stream !l !r = VFSM.Stream step l
  where
    step x
      | x < r     = return $ VFSM.Yield x (x + 1)
      | otherwise = return $ VFSM.Done
    {-# INLINE [0] step #-}
{-# INLINE [1] stream #-}

rep :: Monad m => Int -> (Int -> m ()) -> m ()
rep n = flip VFSM.mapM_ (stream 0 n)
{-# INLINE rep #-}

type UnionFind = VUM.IOVector Int

newUF :: Int -> IO UnionFind
newUF n = VUM.replicate n (-1)
{-# INLINE newUF #-}

rootUF :: UnionFind -> Int -> IO Int
rootUF uf x = do
  p <- VUM.unsafeRead uf x
  if p < 0
    then return x
    else do
      r <- rootUF uf p
      VUM.unsafeWrite uf x r
      return r
{-# INLINE rootUF #-}

connectedUF :: UnionFind -> Int -> Int -> IO Bool
connectedUF uf x y = liftM2 (==) (rootUF uf x) (rootUF uf y)
{-# INLINE connectedUF #-}

uniteUF :: UnionFind -> Int -> Int -> IO ()
uniteUF uf x y = do
  a <- rootUF uf x
  b <- rootUF uf y
  when (a /= b) $ do
    ar <- VUM.unsafeRead uf a
    br <- VUM.unsafeRead uf b
    let (p, c) = if ar < br then (a, b) else (b, a)
    when (ar == br) $ VUM.unsafeModify uf pred p
    VUM.unsafeWrite uf c p

connectGroupUF :: UnionFind -> IO Int
connectGroupUF uf = VU.length . VU.filter (>= 0) <$> VU.unsafeFreeze uf
{-# INLINE connectGroupUF #-}

sizeUF :: UnionFind -> Int -> IO Int
sizeUF uf = fix $ \loop x -> do
  px <- VUM.unsafeRead uf x
  if px < 0
    then return $! negate px
    else loop px
{-# INLINE sizeUF #-}

main :: IO ()
main = do
  [n, m] <- map read . words <$> getLine
  uf <- newUF n
  rep m $ \_ -> do
    (a, b) <- parse2
    uniteUF uf (a-1) (b-1)
  rep n $ \i -> do
    print . succ =<< rootUF uf i
0