{-# LANGUAGE BangPatterns #-} {-# OPTIONS_GHC -O2 #-} module Main where import Data.Maybe (fromJust) import qualified Data.ByteString.Char8 as BS import Control.Monad (replicateM, replicateM_) tuplify2 (x:y:_) = (x,y) tuplify2 _ = undefined --Input functions with ByteString readInt = fst . fromJust . BS.readInteger readIntTuple = tuplify2 . map readInt . BS.words readIntList = map readInt . BS.words getInt = readInt <$> BS.getLine getIntList = readIntList <$> BS.getLine getIntNList n = map readIntList <$> replicateM (fromIntegral n) BS.getLine getIntMatrix = map readIntList . BS.lines <$> BS.getContents getIntTuple = readIntTuple <$> BS.getLine getIntNTuples n = map readIntTuple <$> replicateM (fromIntegral n) BS.getLine getIntTuples = map readIntTuple . BS.lines <$> BS.getContents {-| Max Weighted Floor (mwf) mwf(n,m,a,b,c,d) = max_{0 <= x < n} a*x + b*floor((c*x + d)/m) を返す非再帰(反復)実装。 前提: - n > 0, m > 0 計算量/メモリ: - 時間: O(log m)(ユークリッド互除法的再帰による構造縮約) - 追加メモリ: O(1) -} mwf :: Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Integer mwf n0 m0 a0 b0 c0 d0 = let !sum0 = 0 !max0 = b0 * (d0 `div` m0) -- x = 0 のとき in go n0 m0 a0 b0 c0 d0 sum0 max0 where go :: Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Integer go !n !m !a !b !c !d !sumacc !maxacc = -- 正規化(c,d を 0..m-1 に) let (qc, c') = c `divMod` m !a' = a + b * qc (qd, d') = d `divMod` m !sumacc' = sumacc + b * qd -- y_max = max_{0<=x= 0 && b >= 0) || (a' <= 0 && b <= 0) then maxacc' else -- 小問題へのパラメータ変換 if a' >= 0 then go ymax c' b a' m (m - d' - 1) sumacc' maxacc' else go ymax c' b a' m (m - d' - 1) (sumacc' + a' + b) maxacc' {-| max_{l <= x < r} a*x + b*floor((c*x + d)/m) を返す。 既存の mwf(n,m,...)(0 <= x < n)を用いる。 前提: l < r, m > 0 -} mwfLr :: Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Integer mwfLr l r m a b c d | l >= r || m <= 0 = error "mwfLR: require l < r and m > 0" | otherwise = let n = r - l (q, d') = (c * l + d) `divMod` m in a * l + b * q + mwf n m a b c d' {-| 入出力(複数ケース) -} solve :: IO () solve = do t <- getInt replicateM_ (fromIntegral t :: Int) $ do [n, m, a, b, c, d] <- getIntList print (mwf n m a b c d) main :: IO () main = solve