{-# LANGUAGE BangPatterns #-} {-# LANGUAGE MagicHash #-} import Control.Monad import Data.Bits import Data.IORef import Data.Word import GHC.Exts import Unsafe.Coerce import qualified Data.Vector.Fusion.Stream.Monadic as VFSM import qualified GHC.Integer.GMP.Internals as GMP ------------------------------------------------------------------------------- -- Main ------------------------------------------------------------------------------- main :: IO () main = do n <- readLn :: IO Int ans <- newIORef (0 :: Int) rep' n $ \i -> rep' i $ \j -> rep' n $ \k -> when (5 * i + 2 * j + 3 * k == n) $ modifyIORef' ans succ print =<< readIORef ans ------------------------------------------------------------------------------- -- Utils ------------------------------------------------------------------------------- -- * integer fi :: Int -> Integer fi = fromIntegral {-# INLINE fi #-} fI :: Integer -> Int fI = fromInteger {-# INLINE fI #-} ceilPow2 :: Int -> Int ceilPow2 n | n > 1 = (-1) .>>>. (clz (n - 1)) + 1 | otherwise = 1 floorPow2 :: Int -> Int floorPow2 n | n >= 1 = 1 .<<. (63 - (clz n)) | otherwise = 0 powModInt :: Int -> Int -> Int -> Int powModInt a n mo = fI $ GMP.powModInteger (fi a) (fi n) (fi mo) recipModInt :: Int -> Int -> Int recipModInt a mo = fI $ GMP.recipModInteger (fi a) (fi mo) floorSqrt :: Int -> Int floorSqrt = floor . sqrt . fromIntegral floorLog2 :: Int -> Int floorLog2 x = fromIntegral $ y .>>. 52 - 1023 where y :: Word64 y = unsafeCoerce (fromIntegral x :: Double) -- //integer -- * bits infixl 8 .<<., .>>. infixl 6 .^. (.<<.) :: Bits b => b -> Int -> b (.<<.) = unsafeShiftL {-# INLINE (.<<.) #-} (.>>.) :: Bits b => b -> Int -> b (.>>.) = unsafeShiftR {-# INLINE (.>>.) #-} (.^.) :: Bits b => b -> b -> b (.^.) = xor {-# INLINE (.^.) #-} clz :: FiniteBits fb => fb -> Int clz = countLeadingZeros {-# INLINE clz #-} ctz :: FiniteBits fb => fb -> Int ctz = countTrailingZeros {-# INLINE ctz #-} infixl 8 .>>>. (.>>>.) :: Int -> Int -> Int (.>>>.) (I# x#) (I# i#) = I# (uncheckedIShiftRL# x# i#) {-# INLINE (.>>>.) #-} -- //bits -- * for 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 #-} rep' :: Monad m => Int -> (Int -> m ()) -> m () rep' n = flip VFSM.mapM_ (stream 0 (n + 1)) {-# INLINE rep' #-} rep1 :: Monad m => Int -> (Int -> m ()) -> m () rep1 n = flip VFSM.mapM_ (stream 1 (n + 1)) {-# INLINE rep1 #-} streamR :: Monad m => Int -> Int -> VFSM.Stream m Int streamR !l !r = VFSM.Stream step (r - 1) where step x | x >= l = return $ VFSM.Yield x (x - 1) | otherwise = return $ VFSM.Done {-# INLINE [0] step #-} {-# INLINE [1] streamR #-} rev :: Monad m => Int -> (Int -> m ()) -> m () rev n = flip VFSM.mapM_ (streamR 0 n) {-# INLINE rev #-} rev' :: Monad m => Int -> (Int -> m ()) -> m () rev' n = flip VFSM.mapM_ (streamR 0 (n + 1)) {-# INLINE rev' #-} rev1 :: Monad m => Int -> (Int -> m ()) -> m () rev1 n = flip VFSM.mapM_ (streamR 1 (n + 1)) {-# INLINE rev1 #-} streamStep :: Monad m => Int -> Int -> Int -> VFSM.Stream m Int streamStep !l !r !d = VFSM.Stream step l where step x | x < r = return $ VFSM.Yield x (x + d) | otherwise = return $ VFSM.Done {-# INLINE [0] step #-} {-# INLINE [1] streamStep #-} repStep :: Monad m => Int -> Int -> Int -> (Int -> m ()) -> m () repStep l r d = flip VFSM.mapM_ (streamStep l r d) {-# INLINE repStep #-} repStep' :: Monad m => Int -> Int -> Int -> (Int -> m ()) -> m () repStep' l r d = flip VFSM.mapM_ (streamStep l (r + 1) d) {-# INLINE repStep' #-} -- //for