給出乙個含有若干個不相交矩形的平面直角座標系,以及起點和終點。
從起點到終點的路途中,不能經過矩形,但是可以在矩形邊經過。
求最短的曼哈頓距離。
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最大值 考慮如何...