1. 程式人生 > >【Codeforces 331D3】Escaping on Beaveractor

【Codeforces 331D3】Escaping on Beaveractor

單點 所有 另一個 force 求值 可能 題意 思路 def

題意:給\(b\times b\)的網格,其中有\(n\)個不交叉的箭頭。

現在有\(q\)個詢問,每個詢問包含一個點\((x,y)\),以及一個方向\(dir\)、時間\(t\)

要求從\((x,y)\)開始沿\(dir\)方向走\(t\)秒,每秒前進一格,到了箭頭上就把方向改為箭頭的方向。

問最後會到哪裏。如果會走出網格的話就輸出最後一個在網格內的點。

思路:線段樹+倍增。

先想一個naive的做法。

我們先naive地求出每一個點下一步會朝向那個方向,

然後倍增地搞從某個點走多少步會到哪裏。

那麽這個是\(O(b^2\ log\ t)\)的。

下面來考慮優化。

首先發現我們肯定不用把所有的點都拎出來。

我們只需要可能會用到的點。

首先每一個箭頭的尾端肯定會用到。

從尾端、詢問點走出去碰到的第一個在箭頭上的點肯定會用到。

其它的就不用了。
那麽我們現在要求的是一堆這樣的詢問:

給一堆點和一堆方向,求從它們走出去會碰到箭頭上的哪一點。

那分方向討論後就變成一個區間賦最大值,單點求值的問題。

果斷zkw線段樹優化。但是分方向討論好難寫啊qwq

那麽後面就倍增從某個點開始走幾條邊(邊就是碰到另一個可能會用到的點)之後到了那個點,需要多少時間。

然後就是這裏爆long long了,\((1<<50)*10^5 \geq LongLongMax\)\(wa43\)了半天。

那麽查詢的時候倍增完最後直接沿著那時的方向再走一點就好了。

【Codeforces 331D3】Escaping on Beaveractor