CF 740 D - Alyona and a tree
問題
問題概要
頂点数の木があり、各頂点にはからまでの番号が振られている。根の頂点番号はである。各頂点はそれぞれ整数を持っている。
また、辺には重みがあり、本の辺の情報について、個目の情報は頂点とを結んでおり、その重みはである。
いま、頂点が頂点をcontrol
しているということを次のように定義する:
- 頂点はを根とする部分木に含まれる
各頂点に対して、その頂点がcontrol
している頂点の個数を求めよ。
アイデア
control
の条件に関して、との距離で定義されているが、今回のグラフは木なので任意の頂点間の距離は根からの距離を利用することで計算できる。根からの各頂点への距離をとすると、control
の定義からはよりも根から離れていることになるので2番目の条件はとなり、更に変数を揃えるために変形するとということになる。
さて、ここでを固定して考えてみる。としてあり得るのは根からのへのパス上にある頂点ということになる。根をスタート地点としては単調増加するので、初めて条件を満たす位置からの手前までの区間がこの条件を満たすのでこの区間に+1すればいいということになる。
まず、初めて条件を満たす位置を探すためには、各頂点からの親をダブリングして保存しておけば二分探索によって探すことが可能になる。
そして、このような区間へのaddはimos法での親の頂点に+1,の親の頂点に-1をしておいて最後に子から親へ足し上げれば答えを出すことが出来る。
実装(C++)
続きを読むCF 738 F - Financiers Game
問題
問題概要
長さの数列が与えられる。この数列を使って、LさんとRさんの2人でゲームを行う。
ゲームはLさんのターンで始まる。まず、Lさんは数列の左端からスタートし、そこから1つか2つの値を数列から取り除きその合計を自分のスコアとすることが出来る。次にRさんのターンとなる。Rさんは数列の右端からスタートする。この時、その前の段階でLさんが数列から取った個数が個である時に、Rさんは個または個の値を数列の右端から順に取ることが出来る。
以下、交互に繰り返す。パスは出来ない。数列の値が取り尽くされるか、これ以上選べない状況になってしまったらそこでゲームを終了する。
D = (Lさんの合計スコア) - (Rさんの合計スコア)
とすると、LさんはDを最大化するように、RさんはDを最小化するように最適に行動する時、Dの値を求めよ。
アイデア
DPで解くことを考えてみる。すると、必要な情報は数列の左端、右端、直前のターンで相手が取った個数、今どちらのターンかの4つになると考えられる。
ここで、今Lさんのターンで、上のような状況でのDを、Rさんのターンで同様の状況でのDをとすると、それぞれは次のような遷移で更新していくことが可能になる:
これらを計算することで答えとなる。このDPの計算量は見た目上に見えるが、実際そうではないことを確かめる。
まずに注目すると、に到達するために最低でも個の値が既に数列から取られている状況であることを考えると、という条件が成り立ち、は以下となることが確定する。
更に、LさんとRさんが取る値の個数の差に注目する。最も差が大きくなるような状況は、一方が前者と同じだけ、もう片方が+1になるような選び方をし続けるような状況だが、これを考慮するととなることが分かる。の定義より、となるので、上で触れたDPをの3つの変数の形に変えることによって、で実現することが可能になる。
このDPの計算量の落とし方はかなり面白かったし勉強になった。