Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ad088f9

Browse files
committed
ABC175-D
1 parent 0af3e04 commit ad088f9

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

‎abc/abc175-d/Main.hs‎

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
-- https://github.com/minoki/my-atcoder-solutions
2+
{-# LANGUAGE BangPatterns #-}
3+
import Data.Char (isSpace)
4+
import Data.Int (Int64)
5+
import Data.List (unfoldr)
6+
import qualified Data.Vector.Unboxed as U
7+
import qualified Data.ByteString.Char8 as BS
8+
import qualified Data.IntSet as IntSet
9+
import Control.Exception (assert)
10+
import qualified Test.QuickCheck as QC
11+
import GHC.Stack (HasCallStack)
12+
13+
(!) :: (HasCallStack, U.Unbox a) => U.Vector a -> Int -> a
14+
(!) = (U.!)
15+
{-
16+
(!) vec i | i < 0 = error $ "negative index: " ++ show i
17+
| i >= U.length vec = error $ "out of bounds " ++ show (i,U.length vec)
18+
| otherwise = vec U.! i
19+
-}
20+
21+
cycles :: Int -> U.Vector Int -> [[Int]]
22+
cycles !n perm = loop (IntSet.fromDistinctAscList [0..n-1])
23+
where
24+
loop s | IntSet.null s = []
25+
| otherwise = let (m,s') = IntSet.deleteFindMin s
26+
(cyc,s'') = oneCycle m m [m] s'
27+
in cyc : loop s''
28+
oneCycle m0 m xs s = let m' = perm ! m
29+
in if m' == m0 then
30+
(xs, s)
31+
else
32+
oneCycle m0 m' (m':xs) (IntSet.delete m' s)
33+
34+
solve :: Int -> Int -> U.Vector Int -> U.Vector Int64 -> Int64
35+
solve !n !k perm c = maximum $ map solveOneCycle $ cycles n perm
36+
where
37+
solveOneCycle cyc =
38+
let scores = U.fromList $ map (c !) cyc
39+
cycle_len = U.length scores
40+
t = U.sum scores
41+
scores' = U.init $ scores <> scores
42+
ss = U.scanl' (+) 0 scores'
43+
!_ = assert (U.length ss == 2 * cycle_len)
44+
in if t <= 0 || k <= cycle_len then
45+
maximum [ ss ! j - ss ! i
46+
| i <- [0 .. cycle_len - 1]
47+
, j <- [i + 1 .. min (2 * cycle_len - 1) (i + k)]
48+
]
49+
else
50+
let (q,r) = k `quotRem` cycle_len
51+
-- q >= 1
52+
in t * fromIntegral q + if r == 0 then
53+
max 0 $ maximum [ ss ! j - ss ! i
54+
| i <- [0 .. cycle_len - 1]
55+
, j <- [i + 1 .. min (2 * cycle_len - 1) (i + cycle_len)]
56+
] - t
57+
else
58+
maximum [ ss ! j - ss ! i
59+
| i <- [0 .. cycle_len - 1]
60+
, j <- [i + 1 .. min (2 * cycle_len - 1) (i + r)]
61+
]
62+
63+
main = do
64+
[n,k] <- unfoldr (BS.readInt . BS.dropWhile isSpace) <$> BS.getLine
65+
perm <- U.map (subtract 1) <$> U.unfoldrN n (BS.readInt . BS.dropWhile isSpace) <$> BS.getLine
66+
c <- U.map fromIntegral <$> U.unfoldrN n (BS.readInt . BS.dropWhile isSpace) <$> BS.getLine
67+
print $ solve n k perm c
68+
69+
prop :: QC.Property
70+
prop = let gen = do n <- QC.choose (2, 100)
71+
-- n <- QC.choose (2, 5000)
72+
k <- QC.choose (1, 10^9)
73+
perm <- QC.shuffle [0..n-1]
74+
c <- QC.vectorOf n (QC.choose (-10^9, 10^9))
75+
return (n, k, U.fromList perm, U.fromList c)
76+
in QC.forAll gen (\(n,k,perm,c) -> solve n k perm c `seq` ())

‎abc/abc175-d/genrandinput.lua‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
local n = tonumber(arg[1]) or 1000
2+
local k = tonumber(arg[2]) or 2324532
3+
4+
math.randomseed(os.time())
5+
6+
local P,C = {},{}
7+
for i = 1,n do
8+
P[i] = i
9+
C[i] = math.random(-10^9, 10^9)
10+
end
11+
12+
for i = 1,n-1 do
13+
local j = math.random(i+1,n)
14+
-- P[i],P[j] = P[j],P[i]
15+
P[i],P[i+1] = P[i+1],P[i]
16+
end
17+
18+
io.write(string.format("%d %d\n", n, k))
19+
io.write(table.concat(P," "),"\n")
20+
io.write(table.concat(C," "),"\n")

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /