感謝orz神·小黑的指導
kd-tree就是用來計算若干維空間k近/遠點的數(shou)據(suo)結(you)構(hua)
建樹
假設題目是k維的點
第deep層就是用deep%k+1維把所有點分為兩塊
取deep%k+1維中位數的點做為當前子樹的根節點
再把該維比這個點小的點扔到左子樹 比這個點大的扔到右子樹 遞迴處理
詳見**
1查詢void sort(ll l,ll r,ll k)
2ll build(ll l,ll r,ll deep)
7sort(l,r,deep);
8 ll mid=(l+r)/2;9
if (l1,deep%k+1
);10
else kd[mid].lc=0;11
if (mid1,r,deep%k+1
);12
else kd[mid].rc=0;13
return
mid;
14 }
詢問離點s的前m近點 說它是搜尋優化就是因為這裡- -
維護大根堆記錄答案 當元素個數小於m時直接push
反正判斷有木有 比最大值小 有就pop再push
當搜尋當t點是先用該點到s的距離維護堆
再判斷如果s的deep%k+1維 比t點該維小就先搜尋左子樹 否則搜尋右子樹
**
1最遠點void
push(ll t)
9 }else13}
14void
makeans(ll t,ll deep)else
24 }
這裡講的都是m近點- -
如果是m遠點其實是差不多的 只是維護的東西不太一樣
需要維護每維的min和max
詢問的時候基本同理yy下即可
求k位距離s的m近點**
1 #include 2 #include 3 #include 4 typedef longview codelong
ll;5
using
namespace
std;
6const ll n=50001;7
struct
inpopoi[n],s,ans[11
];10
struct
inkd
15}kd[n];
16struct
info
20};
21 priority_queue que;
22ll root,n,k,m,t,cmpp,size;
23 inline bool
operator
24 inline bool cmp(inkd a,inkd b)
25void sort(ll l,ll r,ll k)
26 ll sqr(ll x)
27ll getdis(inpo a,inpo b)
32ll build(ll l,ll r,ll deep)
37sort(l,r,deep);
38 ll mid=(l+r)/2;39
if (l1,deep%k+1
);40
else kd[mid].lc=0;41
if (mid1,r,deep%k+1
);42
else kd[mid].rc=0;43
return
mid;44}
45void
push(ll t)
53 }else57}
58void
makeans(ll t,ll deep)else68}
69int
main()
77 root=build(1,n,1
);78 scanf("
%i64d
",&t);
79for (;t;t--)
89for (ll i=m;i;i--)
94 puts(""
);95}96
}97}98
fclose(stdin);
99fclose(stdout);
100 }
專題四總結
圖的定義 很簡單,g v,e v e分別表示點和邊的集合。圖的表示 主要有兩種,鄰接矩陣和鄰接表,前者空間複雜度,o v2 後者為o v e 因此,除非非常稠密的圖 邊非常多 一般後者優越於前者。圖的遍歷 寬度遍歷bfs start 1 佇列q empty,陣列bool visited v q.pu...
專題四總結
專題四總結 專題四圖演算法,到目前為止學習了並查集,最小生成樹,最短路。並查集找父節點 int find int x 練習四1003 另一種 int find int a 練習四1022 最小生成樹只會用kruscul 演算法,用這乙個能做不少題了也就懶得學 primer.double kru re...
dp專題總結
1 做題感覺 大部分時候看到題感覺一頭霧水,在明確告訴這是動態規劃的題時會刻意往這方面想,縮小問題規模。如果沒說的話,可能根本不會朝這方面去想。感覺好難做起來理解起來都很費勁,專題中有很多題是稍微變了一下,就暈了,會在各方面細節出問題。就像登山問題和合唱團問題,感覺他們一模一樣,樣例也通過了,就是過...