Submission #229561


Source Code Expand

{-# OPTIONS_GHC -O2 -funbox-strict-fields #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE TupleSections #-}

import Control.Applicative
import Control.Monad
import Data.Bits
import qualified Data.ByteString.Char8 as BS
import Data.Function
import Data.List
import qualified Data.Vector.Generic as G
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector.Unboxed.Mutable as UM
import GHC.Exts (Int, MutableByteArray#, newByteArray#, readIntArray#, writeIntArray#, Int(..))
import GHC.ST (ST, ST(..))

main :: IO ()
main = do
  n <- readLn
  vec <- U.replicateM n $ do
    [a, b] <- getInts
    return (a, b)
  print $ solve vec

solve :: U.Vector (Int, Int) -> Int
solve vec = negate $ U.minimum $ U.scanl (+) 0 $ U.map snd $ heapsort $ U.map (,-1) ins U.++ U.map (,1) outs
  where
    !(ins, outs) = U.unzip vec

----------------------------------------------------------------------------
-- IO

getInts :: IO [Int]
getInts = readInts <$> BS.getLine

readInts :: BS.ByteString -> [Int]
readInts s0 = unfoldr step s0
  where
    step (BS.dropWhile (==' ') -> s)
      | s == "" = Nothing
      | Just (v, r) <- BS.readInt s = Just (v, r)
      | otherwise = error $ "not an integer: " ++ show s

----------------------------------------------------------------------------
-- MHeap

data MHeap s k a = MHeap
  { mhSize :: {-# UNPACK #-} !(MBA s)
  , mhKeys :: !(UM.MVector s k)
  , mhVals :: !(UM.MVector s a)
  }

heapsort :: (UM.Unbox a, Ord a) => U.Vector a -> U.Vector a
heapsort = U.map fst . heapsortKV . U.map (,())

heapsortKV :: (UM.Unbox k, Ord k, UM.Unbox a) => U.Vector (k, a) -> U.Vector (k, a)
heapsortKV xs = U.create $ do
  mv <- UM.new $ U.length xs
  h <- newMH $ U.length xs
  U.forM_ xs $ \(k, v) -> insertMH h k v
  flip fix 0 $ \loop !i -> do
    r <- deleteMH h
    case r of
      Nothing -> return ()
      Just (k, v) -> do
        UM.write mv i (k, v)
        loop $! i + 1
  return mv

deleteMH :: (UM.Unbox k, Ord k, UM.Unbox a) => MHeap s k a -> ST s (Maybe (k, a))
deleteMH MHeap{mhSize=szV, mhVals=vals, mhKeys=keys} = do
  sz <- readIntMBA szV 0
  let !sz' = sz - 1
  if sz' < 0
    then return Nothing
    else do
      outKey <- UM.unsafeRead keys 0
      outVal <- UM.unsafeRead vals 0
      writeIntMBA szV 0 sz'
      key <- UM.unsafeRead keys sz'
      val <- UM.unsafeRead vals sz'
      loop sz' 0 key val
      return $ Just (outKey, outVal)
  where
    loop !sz !pos !(forceU -> key) !(forceU -> val)
      | lch >= sz = do
        UM.unsafeWrite keys pos key
        UM.unsafeWrite vals pos val
      | otherwise = do
        lkey <- UM.unsafeRead keys lch
        (!ch, forceU -> !ckey, forceU -> !cval) <-
          if rch >= sz
            then do
              lval <- UM.unsafeRead vals lch
              return (lch, lkey, lval)
            else do
              rkey <- UM.unsafeRead keys rch
              if lkey < rkey
                then do
                  lval <- UM.unsafeRead vals lch
                  return (lch, lkey, lval)
                else do
                  rval <- UM.unsafeRead vals rch
                  return (rch, rkey, rval)
        if key < ckey
          then do
            UM.unsafeWrite keys pos key
            UM.unsafeWrite vals pos val
          else do
            UM.unsafeWrite keys pos ckey
            UM.unsafeWrite vals pos cval
            loop sz ch key val
      where
        !lch = 2 * pos + 1
        !rch = lch + 1

forceU :: (U.Unbox a) => a -> a
forceU x = G.elemseq (vec x) x x
  where
    vec :: a -> U.Vector a
    vec = undefined
{-# INLINE forceU #-}

insertMH :: (UM.Unbox k, Ord k, UM.Unbox a) => MHeap s k a -> k -> a -> ST s ()
insertMH MHeap{mhSize=szV, mhVals=vals, mhKeys=keys} !key !val = do
  sz <- readIntMBA szV 0
  let !sz' = sz + 1
  --trace ("insert: sz'=" ++ show sz') $ return ()
  when (sz' > UM.length vals) $ overflowErrorMH $! UM.length vals
  writeIntMBA szV 0 sz'
  loop sz
  where
    loop 0 = do
      UM.unsafeWrite keys 0 key
      UM.unsafeWrite vals 0 val
    loop pos = do
      parent <- UM.unsafeRead keys pos'
      if parent <= key
        then do
          UM.unsafeWrite keys pos key
          UM.unsafeWrite vals pos val
        else do
          UM.unsafeWrite keys pos parent
          UM.unsafeWrite vals pos =<< UM.unsafeRead vals pos'
          loop pos'
      where
        !pos' = (pos - 1) `shiftR` 1

overflowErrorMH :: Int -> ST s ()
overflowErrorMH s = fail $ "insertMH: overflow (cap=" ++ show s ++ ")"
{-# NOINLINE overflowErrorMH #-}

newMH :: (UM.Unbox k, UM.Unbox a) => Int -> ST s (MHeap s k a)
newMH cap = MHeap
  <$> do
    r <- newMBA 8
    writeIntMBA r 0 0
    return r
  <*>  UM.new cap
  <*>  UM.new cap

----------------------------------------------------------------------------
-- MBA

data MBA s = MBA (MutableByteArray# s)

readIntMBA :: MBA s -> Int -> ST s Int
readIntMBA (MBA mba) (I# ofs) = ST $ \s -> let
  !(# s1, val #) = readIntArray# mba ofs s
  in (# s1, I# val #)
{-# INLINE readIntMBA #-}

writeIntMBA :: MBA s -> Int -> Int -> ST s ()
writeIntMBA (MBA mba) (I# ofs) (I# val) = ST $ \s -> let
  !s1 = writeIntArray# mba ofs val s
  in (# s1, () #)
{-# INLINE writeIntMBA #-}

newMBA :: Int -> ST s (MBA s)
newMBA (I# bytes) = ST $ \s -> let
  !(# s1, mba #) = newByteArray# bytes s
  in (# s1, MBA mba #)

Submission Info

Submission Time
Task C - AtColor
User mkotha
Language Haskell (GHC 7.4.1)
Score 100
Code Size 5431 Byte
Status AC
Exec Time 189 ms
Memory 13016 KB

Judge Result

Set Name Sample Subtask1 Subtask2
Score / Max Score 0 / 0 30 / 30 70 / 70
Status
AC × 2
AC × 17
AC × 42
Set Name Test Cases
Sample subtask0_sample01.txt, subtask0_sample02.txt
Subtask1 subtask1_01.txt, subtask1_02.txt, subtask1_03.txt, subtask1_04.txt, subtask1_05.txt, subtask1_06.txt, subtask1_07.txt, subtask1_08.txt, subtask1_09.txt, subtask1_10.txt, subtask1_11.txt, subtask1_12.txt, subtask1_13.txt, subtask1_14.txt, subtask1_15.txt, subtask0_sample01.txt, subtask0_sample02.txt
Subtask2 subtask0_sample01.txt, subtask0_sample02.txt, subtask1_01.txt, subtask1_02.txt, subtask1_03.txt, subtask1_04.txt, subtask1_05.txt, subtask1_06.txt, subtask1_07.txt, subtask1_08.txt, subtask1_09.txt, subtask1_10.txt, subtask1_11.txt, subtask1_12.txt, subtask1_13.txt, subtask1_14.txt, subtask1_15.txt, subtask2_01.txt, subtask2_02.txt, subtask2_03.txt, subtask2_04.txt, subtask2_05.txt, subtask2_06.txt, subtask2_07.txt, subtask2_08.txt, subtask2_09.txt, subtask2_10.txt, subtask2_11.txt, subtask2_12.txt, subtask2_13.txt, subtask2_14.txt, subtask2_15.txt, subtask2_16.txt, subtask2_17.txt, subtask2_18.txt, subtask2_19.txt, subtask2_20.txt, subtask2_21.txt, subtask2_22.txt, subtask2_23.txt, subtask2_24.txt, subtask2_25.txt
Case Name Status Exec Time Memory
subtask0_sample01.txt AC 66 ms 1304 KB
subtask0_sample02.txt AC 27 ms 1308 KB
subtask1_01.txt AC 26 ms 1376 KB
subtask1_02.txt AC 28 ms 1324 KB
subtask1_03.txt AC 29 ms 2076 KB
subtask1_04.txt AC 30 ms 2072 KB
subtask1_05.txt AC 30 ms 2076 KB
subtask1_06.txt AC 29 ms 2104 KB
subtask1_07.txt AC 30 ms 2076 KB
subtask1_08.txt AC 30 ms 2076 KB
subtask1_09.txt AC 32 ms 2032 KB
subtask1_10.txt AC 29 ms 2076 KB
subtask1_11.txt AC 30 ms 2076 KB
subtask1_12.txt AC 30 ms 2076 KB
subtask1_13.txt AC 30 ms 2204 KB
subtask1_14.txt AC 31 ms 2080 KB
subtask1_15.txt AC 31 ms 2072 KB
subtask2_01.txt AC 138 ms 12956 KB
subtask2_02.txt AC 144 ms 12836 KB
subtask2_03.txt AC 140 ms 12828 KB
subtask2_04.txt AC 150 ms 12952 KB
subtask2_05.txt AC 151 ms 12956 KB
subtask2_06.txt AC 183 ms 12908 KB
subtask2_07.txt AC 173 ms 12952 KB
subtask2_08.txt AC 181 ms 13016 KB
subtask2_09.txt AC 171 ms 12828 KB
subtask2_10.txt AC 173 ms 12828 KB
subtask2_11.txt AC 171 ms 12952 KB
subtask2_12.txt AC 182 ms 12824 KB
subtask2_13.txt AC 180 ms 12828 KB
subtask2_14.txt AC 172 ms 12828 KB
subtask2_15.txt AC 173 ms 12968 KB
subtask2_16.txt AC 177 ms 12964 KB
subtask2_17.txt AC 173 ms 12892 KB
subtask2_18.txt AC 176 ms 12960 KB
subtask2_19.txt AC 187 ms 12908 KB
subtask2_20.txt AC 189 ms 12960 KB
subtask2_21.txt AC 185 ms 12824 KB
subtask2_22.txt AC 180 ms 12960 KB
subtask2_23.txt AC 182 ms 12960 KB
subtask2_24.txt AC 179 ms 12832 KB
subtask2_25.txt AC 180 ms 12956 KB