atcoder regular contest 028 解説

20
A問題 小石を取るゲーム

Upload: atcoder-inc

Post on 09-Jun-2015

1.355 views

Category:

Documents


1 download

DESCRIPTION

AtCoder Regular Contest 028 解説

TRANSCRIPT

Page 1: AtCoder Regular Contest 028 解説

A問題

小石を取るゲーム

Page 2: AtCoder Regular Contest 028 解説

問題概要

•  袋にN個の小石が入っている。  •  Antさん、Bugくん、Antさん...の順に交互に取っていく。  •  AntさんはA個ずつ、BugさんはB個ずつ小石を取る。  •  どちらのターンの後に袋が空になるかを求めよ。  •  制約 •  1  ≤  N,  A,  B  ≤  1000  

Page 3: AtCoder Regular Contest 028 解説

解法

•  シミュレーションしましょう。 •  カウンタの変数を用意し、そこからAとBを交互に引いていく。

•  カウンタが0以下になったときにどちらのターンだったかを出力する。

Page 4: AtCoder Regular Contest 028 解説

B問題

特別賞

Page 5: AtCoder Regular Contest 028 解説

問題概要

•  コンテストが行われ、N人の人が参加した。 •  i位の人が全参加者のうち何番目に若いかが入力される。

•  1位〜j位の人のうちK番目に若い人の順位を、K~Nのjに対して出力せよ。  

•  制約  •  1  ≤  N  ≤  10^5  

Page 6: AtCoder Regular Contest 028 解説

40点解法  (N≤1000)

•  それぞれの答えを毎回求める。  •  1位からj位までの人の若さをソートして、K番目の要素を見る。  

Page 7: AtCoder Regular Contest 028 解説

満点解法

•  jを小さい方から順番に増やしていき、答えを更新していく。  

•  ある時点でK+1番目以降になった人は、それ以降K番目になる事はない。  

•  1人追加する度に、  –  K+1番目以降だったらなにもしない。  –  K番目以内だったら候補に加え、候補の中から一番老けている人を候補から削除する。  

•  で、候補のうち も老けている人の順位を出力する。  

Page 8: AtCoder Regular Contest 028 解説

満点解法

•  それを実現するためにはデータ構造が必要。必要な操作は、  – 要素を追加する  – 要素のうち も大きい値を取り出す  

•  priority  queue(優先順位つきqueue)  •  各操作をO(log  要素数)で行うことが出来ます。  •  言語によって標準ライブラリがあったりするので調べてみましょう。  

Page 9: AtCoder Regular Contest 028 解説

C問題

高橋王国の分割統治

Page 10: AtCoder Regular Contest 028 解説

問題概要

•  頂点数Nの木が与えられる。  •  頂点vが取り除かれた時にできる連結成分のうち、も大きいものを、各vについて求めよ。  

•  制約  •  1  ≤  N  ≤  10^5  

Page 11: AtCoder Regular Contest 028 解説

30点解法  (N≤1000)

•  それぞれの答えを毎回求める。  •  木の問題になれていれば簡単。  •  DFSなどをすればよい。  

Page 12: AtCoder Regular Contest 028 解説

満点解法

•  とりあえず根付き木として考える。  •  DFSしながら木DPをすれば、子方向の部分木のサイズを求めることが出来る。  

•  しかし、親方向の部分木のサイズはどうしたものだろうか。  

•  →N-­‐1-­‐(子方向の部分木のサイズの和)  で求められる!  

Page 13: AtCoder Regular Contest 028 解説

おまけ

•  詳細については省きますが、  •  部分木のサイズの 大値を求める問題は、木の分割統治を行う時に使ったりします。  

Page 14: AtCoder Regular Contest 028 解説

D問題

注文の多い高橋商店

Page 15: AtCoder Regular Contest 028 解説

問題概要

•  N種類の商品がそれぞれA[i]個ある。  •  「k種類目の商品をx個選ぶとき、合計M個の商品を選ぶ方法は何通りあるか」というクエリにQ回答えよ。  

•  制約  •  1  ≤  N  ≤  2000  •  1  ≤  M  ≤  2000  •  1  ≤  Q  ≤  500000  

Page 16: AtCoder Regular Contest 028 解説

10点解法  (N,M,Q≤100)

•  各クエリそれぞれでDPをする。  •  DP[i][j]=i種類目まででj個選ぶ方法の個数  •  漸化式は  •  DP[i][j]  =  ΣDP[i-­‐1][j-­‐a[i]]~DP[i-­‐1][j]  •  累積和を取っておけばO(1)で更新できる。    

Page 17: AtCoder Regular Contest 028 解説

30点解法  (N,M≤100)

•  商品の順番を入れ替えても答えは変わらない  •  商品i以外だけを使ったときのDPテーブルというのをあらかじめ全てのiについて求めておく。

•  前処理:O(N^2M)  •  各クエリ:O(M)  •  となり、30点を得ることが出来る。  

Page 18: AtCoder Regular Contest 028 解説

80点解法(N,M≤2000,Q≤1000)

•  各iごとに 初からDPをやり直しているのが無駄っぽい  

•  0~jまでを使ったときのDPテーブルと  •  j~Nまでを使ったときのDPテーブル  •  を持っておく。(要するに左側と右側のDPテーブル)  •  各クエリにつき、2つのDPテーブルを参照することで、O(M)で答えを求めることが出来る。  

Page 19: AtCoder Regular Contest 028 解説

満点解法

•  各クエリにO(1)で答えなければならない。  •  商品i以外だけを使ったときのDPテーブルというのをあらかじめ全てのiについて求めておきたい。  

•  考察  •  商品の順番は関係がない  •  DPの漸化式はDP[i-­‐1]における(部分)和の形式

Page 20: AtCoder Regular Contest 028 解説

戻すDP

•  DP[i]からDP[i-­‐1]を復元する。  •  DP[i][j]  =  ΣDP[i-­‐1][j-­‐a[i]]~DP[i-­‐1][j]  •  →  •  DP[i-­‐1][j]  =  DP[i][j]-­‐ΣDP[i-­‐1][j-­‐a[i]]~DP[i-­‐1][j-­‐1]  •  O(M)で復元できる!  •  商品の順番は変えても答えは変わらないので、DP[N]から、「商品i以外だけを使ったときのDPテーブル」が各iについて復元できます。