我正在尝试在Haskell中解决这个问题problem但是时间限制超过了。我应用了我所有的Haskell和数学技能来优化这一点,但都是徒劳的。有人可以建议我如何进一步优化此代码。序列F_3 + F_7 + F_11 .... + F_(4n + 3)= F_2n * F_(2n + 1)。我使用O(log n)方法来计算Fibonacci数。
import Data.List
import Data.Maybe
import qualified Data.ByteString.Lazy.Char8 as BS
matmul :: [Integer] -> [Integer] -> Integer -> [Integer]
matmul [a,b,c] [d,e,f] m = [x,y,z] where
y = (a*e + b*f) `mod` m
z = (b*e + c*f) `mod` m
x = y + z
powM ::[Integer] -> Integer -> Integer -> [Integer]
powM a n m | n == 1 = a
| n == 2 = matmul a a m
| even n = powM ( matmul a a m ) ( div n 2 ) m
| otherwise = matmul a ( powM ( matmul a a m ) ( div n 2 ) m ) m
readInt :: BS.ByteString -> Integer
readInt = fst.fromJust.BS.readInteger
solve::Integer -> BS.ByteString
solve n = BS.pack.show $ mod ( c*d ) 1000000007 where
[c,d,_] = powM [1,1,0] ( 2*n ) 1000000007
--([_,a,_]:_) = powM [[1,2,1],[0,5,3],[0,3,2]] n 1000000007
-- f_3+f_7+f_11+f_15 = f_2n*f_(2n+1)
main = BS.interact $ BS.unlines. map ( solve.readInt ) . tail . BS.lines
答案 0 :(得分:1)
您的解决方案似乎足够快,但似乎您的主要功能不会在每个新行后打印答案。实际上它需要额外的换行才能得到最后的答案,这可能是你超时的原因!这是一个在输入后直接打印每个答案的版本。
import Data.List
import Data.Maybe
import Control.Monad
import qualified Data.ByteString.Lazy.Char8 as B
import qualified Data.ByteString.Char8 as BC
import qualified Text.Show.ByteString as BS
matmul :: [Integer] -> [Integer] -> Integer -> [Integer]
matmul [a,b,c] [d,e,f] m = [x,y,z] where
y = (a*e + b*f) `mod` m
z = (b*e + c*f) `mod` m
x = y + z
powM :: [Integer] -> Integer -> Integer -> [Integer]
powM a n m | n == 1 = a
| n == 2 = matmul a a m
| even n = powM ( matmul a a m ) ( div n 2 ) m
| otherwise = matmul a ( powM ( matmul a a m ) ( div n 2 ) m ) m
solve :: Integer -> Integer
solve n = mod ( c*d ) 1000000007
where
[c,d,_] = powM [1,1,0] ( 2*n ) 1000000007
readInteger :: B.ByteString -> Integer
readInteger = fst . fromJust . B.readInteger
readInt :: B.ByteString -> Int
readInt = fst . fromJust . B.readInt
get :: IO B.ByteString
get = liftM (B.fromChunks . (:[])) BC.getLine
main :: IO ()
main = do
n <- liftM readInt get
replicateM_ n ( liftM readInteger get >>= B.putStrLn . BS.show . solve )