Cerinta completa

Given an array of integers (), find all possible increasing subsequences of maximum length, . Then print the lexicographically longest increasing subsequence as a single line of space-separated integers; if there are less than subsequences of length , print .

Two subsequences and are considered to be different if there exists at least one such that .

Input Format

The first line contains space-separated integers, and , respectively.
The second line consists of space-separated integers denoting respectively.

Constraints

Scoring

  • for of the test data.
  • for of the test data.

Output Format

Print a single line of space-separated integers denoting the lexicographically longest increasing subsequence; if there are less than subsequences of length , print .

Note: is the length of longest increasing subsequence in the array.

Sample Input 0

5 3
1 3 1 2 5

Sample Output 0

1 3 5

Sample Input 1

5 2
1 3 2 4 5

Sample Output 1

1 3 4 5    

Explanation

Sample Case 0:
The longest possible increasing subsequences in lexicographical order are:

Notice that the first and second subsequences appear the same; they are actually both different because the in the first subsequence comes from array element , and the in the second subsequence comes from array element . Because , we print the one () as a single line of space-separated integers.

Sample Case 1:
The longest possible increasing subsequences in lexicographical order are:

Because , we print the one () as a single line of space-separated integers.


Limbajul de programare folosit: haskell

Cod:

{-# LANGUAGE ScopedTypeVariables #-}

-- via editorial
module Main where

import qualified Data.Vector.Unboxed as U
import qualified Data.Vector as V
import qualified Data.Vector.Mutable as M
import qualified Data.Vector.Unboxed.Mutable as UM
import Data.List
import Control.Monad.ST
import Control.Monad.Primitive
import Data.Bits
import Data.Function
import Data.Maybe

main :: IO ()
main = do
  [_, k] <- fmap (map read . words) getLine :: IO [Int]
  as <- fmap (U.fromList . map read . words) getLine :: IO A
  let gs = stage1 as
  let rcs = stage2 as gs
  putStrLn (stage3 as gs rcs k)
  
type A = UVec Int
type G = [[Int]]
type C = UVec Int
type UVec = U.Vector
type UMVec s a = UM.MVector s a

stage1 :: A -> G
stage1 as = runST $ do
  bs <- UM.replicate (succ n) 0
  gs <- M.replicate (succ n) []
  let
    f [] = return []
    f ((i, a) : xs) = do
      l <- fmap (succ . maximum . (0:)) $ query bs (pred a)
      update bs (max l) a
      M.modify gs (i:) l
      fmap (l:) (f xs)
  ls <- f $ zip [0..] (U.toList as)
  fmap (take (maximum ls) . tail . V.toList) (V.freeze gs)
  where
    n = U.length as

stage2 :: A -> G -> C
stage2 as gs = runST $ do
  bs <- UM.replicate (succ n) 0
  rcs <- UM.new n -- right counts
  sequence_ [UM.write rcs i 1 | i <- last gs]
  let
    handleGroup (g1:gs1) (g2:gs2) = do
      writeCounts g1 g2
      sequence_ [clear bs (succ n - getA i) | i <- g2]
      handleGroup gs1 gs2
    handleGroup _ _ = return ()
    writeCounts (i:g1) g2 = do
      updateBs g3
      rc <- fmap (foldl' add 0) $ query bs (succ n - succ (getA i))
      UM.write rcs i rc
      writeCounts g1 g4
      where
        (g3, g4) = span (> i) g2
    writeCounts _ _ = return ()
    updateBs [] = return ()
    updateBs (i:g1) = do
      rc <- UM.read rcs i
      update bs (add rc) (succ n - getA i)
      updateBs g1
  handleGroup (tail . reverse $ gs) (reverse gs)
  U.freeze rcs
  where
    getA = (as U.!)
    n = U.length as

stage3 :: A -> G -> C -> Int -> String
stage3 as gs rcs k = runST $ do
  bs <- UM.replicate (n + 2) 0
  let
    go _ [] _ = return []
    go k1 (dg:dgs1) ii = do
      mb <- findIi a_mb dg k1
      case mb of
        Nothing -> return []
        (Just (jj_lcs, k2)) -> do
          sequence_ [clear bs (succ i) | i <- ii]
          sequence_ [update bs (add lc) (succ j) | (j, lc) <- jj_lcs]
          let b = getA . fst . head $ jj_lcs
          fmap (b :) (go k2 dgs1 (map fst jj_lcs))
      where a_mb = if null ii then Nothing else (Just (getA (head ii)))
    findIi _ [] _ = return Nothing
    findIi a_mb (ii:iis) k1
      | isJust a_mb && b <= a = findIi a_mb iis k1
      | otherwise = do
        lcs <- if isJust a_mb then sequence [fmap (foldl' add 0) (query bs (succ i)) | i <- ii] else return (repeat 1) -- left counts
        let k2 = foldl' add 0 [mult lc (getRCount i) | (lc, i) <- zip lcs ii]
        if k2 < k1 then findIi a_mb iis (k1 - k2) else return (Just (zip ii lcs, k1))
      where
        b = getA (head ii)
        (Just a) = a_mb
  xs <- go k dgs []
  return $ if null xs then "-1" else (intercalate " " (map show xs))
  where
    n = U.length as
    -- divided groups (groups = indices grouped by left-length, divided = every group is again grouped, now by a-value. these subgroups we call inverse images)
    dgs = [groupBy ((==) `on` getA) . sortBy (compare `on` getA) $ g1 | g1 <- gs]
    getA = (as U.!)
    getRCount = (rcs U.!)
    -- lc = left count = number of ways to reach this position      

query :: PrimMonad m => UMVec (PrimState m) Int -> Int -> m [Int]
query bs i = sequence [UM.read bs j | j <- takeWhile (> 0) (iterate (\x -> x - (x .&. (-x))) i)]

update :: PrimMonad m => UMVec (PrimState m) Int -> (Int -> Int) -> Int -> m ()
update bs f i = sequence_ [UM.modify bs f j | j <- takeWhile (< UM.length bs) (iterate (\x -> x + (x .&. (-x))) i)]

clear :: PrimMonad m => UMVec (PrimState m) Int -> Int -> m ()
clear bs i = sequence_ [UM.write bs j 0 | j <- takeWhile (< UM.length bs) (iterate (\x -> x + (x .&. (-x))) i)]

kBound :: Int
kBound = 10 ^ (18 :: Int) + 1

add :: Int -> Int -> Int
add x y = min (x + y) kBound

mult :: Int -> Int -> Int
mult _ 0 = 0
mult x y = if x > 1 + (kBound `quot` y) then kBound else (x * y)

Scor obtinut: 1.0

Submission ID: 464669102

Link challenge: https://www.hackerrank.com/challenges/super-kth-lis/problem

Super Kth LIS