Submission #52906621


Source Code Expand

import qualified Data.ByteString.Char8 as BS
import Data.Char
import Data.List

import qualified Data.IntMap as IM
import qualified Data.IntSet as IS

import Control.Monad
import Control.Monad.ST
import qualified Data.Vector.Unboxed.Mutable as MUV

main :: IO ()
main = do
  [n] <- bsGetLnInts
  as <- bsGetLnInts
  let ans = abc351f n as
  print ans

bsGetLnInts :: IO [Int]
bsGetLnInts = unfoldr (BS.readInt . BS.dropWhile isSpace) <$> BS.getLine

abc351f :: Int -> [Int] -> Int
abc351f n as = ans
  where
-- Aiの大きい順に背番号
--    a2i = IM.fromList $ zip (IS.toDescList $ IS.fromList as) [0..]
    a2i = IM.fromSet (\k -> maybe 0 (succ . snd) $ IM.lookupGT k a2i) $ IS.fromList as
-- Aiの異なる要素の種類数
    m = succ $ snd $ IM.findMin a2i
-- 総和と個数の両方を足す演算
    op (a,b) (c,d) = (a+c, b+d)
    ans = runST $ do
      st <- makeSegTreeN op (0,0) m :: ST s (SegmentTree (ST s) (Int,Int))
      recur st as
-- リストの後ろから計算する
    recur _st [] = return 0
    recur st (a:as) = do
      acc <- recur st as
      let i = a2i IM.! a
      (v,k) <- querySegTree st 0 i
      modifySegTree st i (op (a, 1))
      return $! acc + v - k * a

data SegmentTree m a = SegmentTree Int (a->a->a) a (MUV.MVector (MUV.PrimState m) a)

{- makeSegTreeN len op u 要素数を指定して単位元で満たされたセグメント木を作る
要素数len 添え字0始まり
op モノイド演算
u opの単位元
-}
makeSegTreeN :: (MUV.Unbox a, MUV.PrimMonad m) => (a->a->a) -> a -> Int -> m (SegmentTree m a)
makeSegTreeN op u len = SegmentTree w op u <$> MUV.replicate (w + pred w) u
  where w = until (len <=) (2 *) 1

{- querySegTree st a b [a, b)の区間をopした結果を求める -}
querySegTree :: (MUV.Unbox a, MUV.PrimMonad m) => SegmentTree m a -> Int -> Int -> m a
querySegTree (SegmentTree w op u arr) a b = loop arr 0 w 0
  where
    loop arr p w i
      | q <= a || b <= p = return u
      | a <= p && q <= b = MUV.read arr i
      | otherwise = do
        l <- loop arr  p       w2 (i + succ i)
        r <- loop arr (p + w2) w2 (2 * succ i)
        return (op l r)
      where
        q = p + w
        w2 = div w 2

{- modifySegTree st i f 要素iにfを適用する -}
modifySegTree :: (MUV.Unbox a, MUV.PrimMonad m) => SegmentTree m a -> Int -> (a -> a) -> m ()
modifySegTree (SegmentTree w op _ arr) j f =
  do
    MUV.modify arr f i0
    forM_ upwards (\i -> do
      l <- MUV.read arr (i + succ i)
      r <- MUV.read arr (2 * succ i)
      MUV.write arr i (op l r)
      )
  where
    i0 = j + pred w
    upwards = tail $ takeWhile (0 <=) $ iterate (flip div 2 . pred) i0

Submission Info

Submission Time
Task F - Double Sum
User joetheshootingst
Language Haskell (GHC 9.4.5)
Score 500
Code Size 2737 Byte
Status AC
Exec Time 1616 ms
Memory 140296 KiB

Compile Error

app/Main.hs:23:9: warning: [-Wunused-matches]
    Defined but not used: ‘n’
   |
23 | abc351f n as = ans
   |         ^

app/Main.hs:37:17: warning: [-Wname-shadowing]
    This binding for ‘as’ shadows the existing binding
      bound at app/Main.hs:23:11
   |
37 |     recur st (a:as) = do
   |                 ^^

app/Main.hs:59:10: warning: [-Wname-shadowing]
    This binding for ‘arr’ shadows the existing binding
      bound at app/Main.hs:57:34
   |
59 |     loop arr p w i
   |          ^^^

app/Main.hs:59:16: warning: [-Wname-shadowing]
    This binding for ‘w’ shadows the existing binding
      bound at app/Main.hs:57:27
   |
59 |     loop arr p w i
   |                ^

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 500 / 500
Status
AC × 2
AC × 11
Set Name Test Cases
Sample 00_sample_00.txt, 00_sample_01.txt
All 00_sample_00.txt, 00_sample_01.txt, 01_random_00.txt, 01_random_01.txt, 01_random_02.txt, 01_random_03.txt, 01_random_04.txt, 01_random_05.txt, 02_corner_00.txt, 02_corner_01.txt, 02_corner_02.txt
Case Name Status Exec Time Memory
00_sample_00.txt AC 1 ms 7120 KiB
00_sample_01.txt AC 1 ms 7108 KiB
01_random_00.txt AC 81 ms 22376 KiB
01_random_01.txt AC 1596 ms 140296 KiB
01_random_02.txt AC 1005 ms 111236 KiB
01_random_03.txt AC 1606 ms 140292 KiB
01_random_04.txt AC 563 ms 72648 KiB
01_random_05.txt AC 1616 ms 140208 KiB
02_corner_00.txt AC 71 ms 44352 KiB
02_corner_01.txt AC 1 ms 7120 KiB
02_corner_02.txt AC 72 ms 52988 KiB