{-# LANGUAGE ImplicitParams #-} import Data.List import Data.Array.Diff import Debug.Trace --trace _ = id -- Boxed DiffArray takes forever for large inputs! emptyT = listArray ((0,0),(2,2)) (repeat 0) :: DiffUArray (Int,Int) Int main = do content <- getContents let hd:tl = lines content let ?totalcases = read hd process 1 $ map (map read) (map words tl) process :: (?totalcases :: Int) -> Int -> [[Integer]] -> IO () process count content = do if count > ?totalcases then return () else case content of ([n,a,b,c,d,x0,y0,m]:tl) -> let g = (x0, y0) : map f g -- :: [(Int,Int)] f (x,y) = ((a * x + b) `mod` m, (c * y + d) `mod` m) -- Initial config of trees inits = map mod3 $ genericTake n g mod3 (x,y) = (fromEnum (mod x 3), fromEnum (mod y 3)) -- Collapse the tree space trees = foldl' k emptyT inits k ar (x,y) = --trace "Here we go" ar // [((x,y), ar!(x,y) + 1)] widen :: ((Int,Int),Int) -> ((Int,Int),Integer) widen ((x,y), z) = ((x,y), toEnum z) in do putStr ("Case #" ++ show count ++ ": ") -- putStrLn $ show $ length inits putStrLn $ show $ work $ map widen $ assocs trees process (count+1) tl take3 n = n * (n-1) * (n-2) `div` 6 --take2 n = n * (n-1) `div` 2 work :: [((Int,Int),Integer)] -> Integer work [] = 0 work (((x,y),z):trees) = let a = if z>=3 then take3 z else 0 -- b = if z>=2 then take2 z else 0 in a -- Take 3 from the first set -- + b * work2 (2*x,2*y) trees -- IMPOSSIBLE to take 2 from the first set and then take another -- Why? Suppose 2x + y = 0. Meanwhile, 3x = 0. So x = y. + work trees -- Take 3 from the rest + z * work1 (x,y) trees -- Take 1 from the first, and take other 2 -- Two vertices have been fixed already work2 _ [] = 0 work2 (x,y) trees = foldl' f 0 trees where f acc ((a,b),c) = acc + d where d = if mod (x+a) 3 == 0 && mod (y+b) 3 == 0 then c else 0 -- One vertice has been fixed already work1 _ [] = 0 work1 (x,y) (((a,b),c):trees) = {- let d = if c>=2 then take2 c else 0 e = if mod (x+2*a) 3 == 0 && mod (y+2*b) 3 == 0 then c else 0 in d*e + -} work1 (x,y) trees + c * work2 (x+a,y+b) trees -- Produces all possible combinations by choosing three elements from a list, too inefficient -- work :: [a] -> [(a,a,a)] -- work trees = let gen3 [a,b,c] = [(a,b,c)] -- gen3 (t:ts) = zipWith f3 (repeat t) (gen2 ts) ++ gen3 ts -- gen2 [a,b] = [(a,b)] -- gen2 (t:ts) = zip (repeat t) ts ++ gen2 ts -- f3 a (b,c) = (a,b,c) -- in -- gen3 trees