choosing balls
DESCRIPTION
Japanese Editorial for CF#162 div1-CTRANSCRIPT
Codeforces #162
Div1-C,Div2-E
Choosing BallsWriter: hogloid
improvement: snuke
cooperation: rng_58,degwer
N個のボールが一列に並んでいます
それぞれのボールには,色・価値が定められています
あるボールの列の価値は以下のように定められます
あるボールが列の先頭,もしくは一つ前のボールと色が違うなら,(ボールの価値)*b
そうでないなら,(ボールの価値)*a
列の価値はボールはこれらの数の和
N個のボールの中から,相対的な順序を変えずに一部のボールを取り出します(部分列を取ります)
(a,b)のペアがQ個与えられるので,それぞれの(a,b)について,選べるボールの部分列の価値の最大値を答えなさい ただし,空の列の価値は0とします。
1<=N<=100000 1<=Q<=500
-100000<=a,b,ボールの価値<=100000
1<=ボールの色<=N
クエリーと聞いて前処理が頭をよぎるかも知れませんが,O(NQ)なら間に合いそう
O(QNlogN)はO(10^9)ぐらいになるのでかなり危険・・・(実際通りません)
それぞれのクエリーについて独立に考えてみます
妥当にDPを考えてみましょう
dp[i]:=列の最後の色がiとなるような部分列の最大価値
i番目のボールの色をColor[i],価値をValue[i]とおくと,
dp[Color[i]] を,
①dp[Color[i]]+a*Value[i] か
②dp[j]+b*Value[i] (1<=j<=N,j!=Color[i])
に更新することができます
ボールを順に見てこの更新を繰り返す
ナイーブな実装で、O(N^2)
①のパターンはO(1)で楽勝
②は、よくあるパターンとしてColor[i]
の左、右で分けると、それぞれの区間の最大値を求め、最大値に+Value[i]*bすればOK
Range Minimum Query&更新!
Segment Tree!!!
しかし、更新/Range Minimum QueryをどちらもO(1)で解くのはセグメント木では無理そう・・・
logが一つかかると、TimeLimitにも間に合いそうにない
別のO(1)で更新する方法を考えよう
dp配列の上位二つの(最後の色、価値)を
持っていれば、あらゆる色でも、違う色の最大値がどちらかにはある
dp配列の値の更新は常に増加するので、
消去などの面倒なことが起こらず、更新はどれもO(1)で可能
少し場合分けが必要です ここでのWAがかなり多かった
First Acceptance: KADR 25m24s
Japanese First Acceptance: Komaki 27m50s
Accepted User/All Rated User/All Submission:236/566/916
普段のCよりかなり解かれました
赤族やそれに準ずる人はCを解けないと厳しかったかもしれません
バグで詰まってる人が多くて悲しかった
First Acceptance: Moor 70m52s
Japanese First Acceptance: ikouki108m6s
Accepted User/All Rated User: 12/1526
Div2-Eとしては理想的な解かれ具合だと思います
これが解ける人は早くdiv1に来ましょう!
いつかまた問題を作ったときはよろしくお願いします
Codeforcesの
トップページを飾った
名誉なLissくん→