6701 2020 06 07省選模擬 旅行

2021-10-06 21:33:26 字數 2227 閱讀 2731

給出乙個含有若干個不相交矩形的平面直角座標系,以及起點和終點。

從起點到終點的路途中,不能經過矩形,但是可以在矩形邊經過。

求最短的曼哈頓距離。

n ≤2

e5

n\leq 2e5

n≤2e5

比賽時認為是歐幾里得距離,所以不存在思考……

先說dyp的做法:

對於乙個點,找到上下左右第乙個碰到的邊界,然後可以形成乙個矩形。這個點可以曼哈頓最短距離到達矩形內任意點。

然後每個頂點以及起點終點向周圍連邊,連的是最近碰到的每個邊界的兩個端點。

然後跑最短路。

在說奇妙的正解:

由於這題的矩形都不相交,於是有些很神奇的性質。

以下建議感性理解,不解釋

首先,橫座標和縱座標至少有乙個是單調的。

假設橫座標單調,如何判斷?

欽定起點在終點左邊,假如起點在終點上面,從起點開始不停往下走,遇到障礙就往右。

一直走到終點所在的那一列,如果這時候縱座標小於終點,那麼就不單調。

接下來考慮如何計算答案。

假如起點在終點左邊。從起點開始往右掃,遇到障礙就分兩路到障礙的兩邊,並且將橫座標移到障礙這裡。(如果沒有遇到障礙,先暫時保持著橫座標不變,具體原因自己去玩)

一直這麼做下去,直到計算過兩列之間的所有障礙。

剩下的距離就是最短的曼哈頓距離。

無法用精準的語言來說明它的正確性,但它就是很對……

這個東西隨便用set維護就可以了。

具體細節在此

using

namespace std;

#include

#include

#include

#include

#include

#define n 200010

int n;

struct dot

} s,t;

struct sqr z[n]

;int ans=int_max;

struct segment seg[n*2]

;int m;

bool

cmp1

(segment a,segment b)

bool

cmp0

(segment a,segment b)

struct status

;bool

operator

<

(status a,status b)

multiset s;

bool

judge()

;sort

(seg+

1,seg+m+

1,cmp1);}

else

;sort

(seg+

1,seg+m+

1,cmp0);}

int x=s.x;

for(

int i=

1;i<=m;

++i)

if(seg[i]

.l.r) x=seg[i]

.r;return x<=t.x;

}void

calc()

;sort

(seg+

1,seg+m+

1,cmp0)

; s.

insert()

;for

(int i=

1;i<=m;

++i)

),u,v;0;

for(

auto q=p;p!=s.

end(

)&& l>y && p-

>y++p,s.

erase

(q))

)/*.first*/

; v=s.

insert

((status)

)/*.first*/;}

else}}

for(

auto p=s.

begin()

;p!=s.

end();

++p)

ans=

min(ans,p-

>s+

(t.x-p-

>x)

+abs

(p->y-t.y));

}int

main()

還是不要總想著資料結構……

有些問題性質很優美的……

OI省選知識

1.陣列 y 2.鍊錶,雙向鍊錶 y 3.佇列,單調佇列,雙端佇列 4.棧,單調棧1.堆 2.並查集與帶權並查集 3.hash 表 自然溢位 雙hash1.樹狀陣列 2.線段樹,線段樹合併 3.平衡樹 treap 隨機平衡二叉樹 y splay 伸展樹 scapegoat tree 替罪羊樹 4.塊...

省選演算法匯集

陣列 鍊錶,雙向鍊錶 佇列,單調佇列,雙端佇列 棧,單調棧 堆並查集與帶權並查集 hash 表 自然溢位 雙hash 樹狀陣列 線段樹,線段樹合併 平衡樹treap 隨機平衡二叉樹 splay 伸展樹 scapegoat tree 替罪羊樹 塊狀陣列,塊狀鍊錶 5.樹套樹 線段樹套線段樹 線段樹套平...

省選模擬 19 09 11

ps.博主趁資訊課摸魚考的暴零模擬 看門人憑感覺就知道是長鏈剖分,將路徑查分一下,dis u di sv 2 dis lc adis u dis v 2 dis disu disv 2 disl ca 維護fu,if fu,i 表示u的子樹,深度為 i 的點的 dis disdi s最大值 考慮如何...