{-# LANGUAGE BangPatterns #-} {-# LANGUAGE FlexibleContexts #-} import Control.Monad import Data.Bits import qualified Data.Array.IO as ArrIO import qualified Data.Vector.Fusion.Stream.Monadic as VFSM main :: IO () main = do [n, k] <- map read . words <$> getLine bit <- newBIT 2000000 rep n $ \_ -> do w <- readLn :: IO Int if w > 0 then do temp1 <- bit -|-! 2000000 temp2 <- bit -|-! (w - 1) when (temp1 - temp2 < k) $ incBIT bit w 1 else do let w' = abs w temp3 <- bit -|-! w' temp4 <- bit -|-! (w' - 1) when (temp3 - temp4 > 0) $ incBIT bit w' (-1) print =<< bit -|-! 2000000 ------------------------------------------------------------------------------- -- Utils ------------------------------------------------------------------------------- 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 #-} ------------------------------------------------------------------------------- -- Binary Indexed Tree ------------------------------------------------------------------------------- infixl 8 .<<., .>>. (.<<.) :: Bits b => b -> Int -> b (.<<.) = unsafeShiftL {-# INLINE (.<<.) #-} (.>>.) :: Bits b => b -> Int -> b (.>>.) = unsafeShiftR {-# INLINE (.>>.) #-} clz :: FiniteBits fb => fb -> Int clz = countLeadingZeros {-# INLINE clz #-} ltPow2 :: Int -> Int ltPow2 n | n >= 1 = 1 .<<. (63 - (clz n)) | otherwise = 0 type BinaryIndexedTree = ArrIO.IOUArray Int Int newBIT :: Int -> IO BinaryIndexedTree newBIT n = ArrIO.newListArray (1, n) $ repeat 0 {-# INLINE newBIT #-} infixl 9 -|-! (-|-!) :: BinaryIndexedTree -> Int -> IO Int bit -|-! i = iter i 0 where iter :: Int -> Int -> IO Int iter z a | z < 1 = return a | otherwise = do b <- (+ a) <$> ArrIO.readArray bit z let j = z - (z .&. (- z)) iter j b sumFromToBIT :: BinaryIndexedTree -> Int -> Int -> IO Int sumFromToBIT bit l r | l >= 2 = (-) <$> bit -|-! r <*> bit -|-! (l - 1) | otherwise = bit -|-! r incBIT :: BinaryIndexedTree -> Int -> Int -> IO () incBIT bit i v = do (_, u) <- ArrIO.getBounds bit iter i u v bit where iter z key value b = when (z <= key) $ do ArrIO.writeArray b z . (+ value) =<< ArrIO.readArray b z iter (z + (z .&. (-z))) key value b readBIT :: BinaryIndexedTree -> Int -> IO Int readBIT bit i = sumFromToBIT bit i (i + 1) writeBIT :: BinaryIndexedTree -> Int -> Int -> IO () writeBIT bit i x = readBIT bit i >>= incBIT bit i . (x - ) findMaxIndexLT :: BinaryIndexedTree -> Int -> IO Int findMaxIndexLT bit w0 | w0 <= 0 = return 0 | otherwise = do n <- snd <$> ArrIO.getBounds bit go w0 (ltPow2 n) 0 n where go !w !step !i !m | step == 0 = return (i + 1) | otherwise = do if i + step < m then do u <- ArrIO.readArray bit (i + step) if u < w then go (w - u) (step .>>. 1) (i + step) m else go w (step .>>. 1) i m else go w (step .>>. 1) i m {-# INLINE findMaxIndexLT #-}