BZOJ1941:[SDOI2010]Hide and Seek(K-D Tree)
Description
小豬iPig在PKU剛上完了無聊的豬性代數課,天資聰慧的iPig被這門對他來說無比簡單的課弄得非常寂寞,為了消除寂寞感,他決定和他的好朋友giPi(雞皮)玩一個更加寂寞的游戲---捉迷藏。 但是,他們覺得,玩普通的捉迷藏沒什么意思,還是不夠寂寞,于是,他們決定玩寂寞無比的螃蟹版捉迷藏,顧名思義,就是說他們在玩游戲的時候只能沿水平或垂直方向走。一番寂寞的剪刀石頭布后,他們決定iPig去捉giPi。由于他們都很熟悉PKU的地形了,所以giPi只會躲在PKU內n個隱秘地點,顯然iPig也只會在那n個地點內找giPi。游戲一開始,他們選定一個地點,iPig保持不動,然后giPi用30秒的時間逃離現場(顯然,giPi不會呆在原地)。然后iPig會隨機地去找giPi,直到找到為止。由于iPig很懶,所以他到總是走最短的路徑,而且,他選擇起始點不是隨便選的,他想找一個地點,使得該地點到最遠的地點和最近的地點的距離差最小。iPig現在想知道這個距離差最小是多少。 由于iPig現在手上沒有電腦,所以不能編程解決這個如此簡單的問題,所以他馬上打了個電話,要求你幫他解決這個問題。iPig告訴了你PKU的n個隱秘地點的坐標,請你編程求出iPig的問題。
Input
第一行輸入一個整數N 第2~N+1行,每行兩個整數X,Y,表示第i個地點的坐標
Output
一個整數,為距離差的最小值。
Sample Input
40 0
1 0
0 1
1 1
Sample Output
1HINT
對于30%的數據,N<=1000 對于100%的數據,N<=500000,0<=X,Y<=10^8 保證數據沒有重點保證N>=2
Solution
$K-D~Tree$板子題……
跑的有點慢于是加了波快讀
Code
1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 #include<cmath> 6 #include<algorithm> 7 #define N (100009) 8 #define INF (2000000000) 9 using namespace std; 10 11 int n,D,Root,tmp1,tmp2,ans=INF,LIM; 12 13 inline int read() 14 { 15 int x=0,w=1; char c=getchar(); 16 while (c<'0' || c>'9') {if (c=='-') w=-1; c=getchar();} 17 while (c>='0' && c<='9') x=x*10+c-'0', c=getchar(); 18 return x*w; 19 } 20 21 struct Node 22 { 23 int ls,rs,d[2],Max[2],Min[2]; 24 bool operator < (const Node &a) const {return d[D]<a.d[D];} 25 }p[N],Q; 26 27 struct KDT 28 { 29 Node T[N]; 30 31 void Pushup(int now) 32 { 33 int ls=T[now].ls,rs=T[now].rs; 34 for (int i=0; i<=1; ++i) 35 { 36 T[now].Max[i]=T[now].Min[i]=T[now].d[i]; 37 if (ls) 38 { 39 T[now].Max[i]=max(T[now].Max[i],T[ls].Max[i]); 40 T[now].Min[i]=min(T[now].Min[i],T[ls].Min[i]); 41 } 42 if (rs) 43 { 44 T[now].Max[i]=max(T[now].Max[i],T[rs].Max[i]); 45 T[now].Min[i]=min(T[now].Min[i],T[rs].Min[i]); 46 } 47 } 48 } 49 int Build(int opt,int l,int r) 50 { 51 if (l>r) return 0; 52 int mid=(l+r)>>1; 53 D=opt; nth_element(p+l,p+mid,p+r+1); 54 T[mid]=p[mid]; 55 T[mid].ls=Build(opt^1,l,mid-1); 56 T[mid].rs=Build(opt^1,mid+1,r); 57 Pushup(mid); return mid; 58 } 59 int Get_Max(int now) 60 { 61 int ans=0; 62 for (int i=0; i<=1; ++i) 63 ans+=max(abs(Q.d[i]-T[now].Min[i]),abs(Q.d[i]-T[now].Max[i])); 64 return ans; 65 } 66 int Get_Min(int now) 67 { 68 int ans=0; 69 for (int i=0; i<=1; ++i) 70 { 71 ans+=max(0,T[now].Min[i]-Q.d[i]); 72 ans+=max(0,Q.d[i]-T[now].Max[i]); 73 } 74 return ans; 75 } 76 void Query_Max(int now) 77 { 78 tmp1=max(tmp1,abs(Q.d[0]-T[now].d[0])+abs(Q.d[1]-T[now].d[1])); 79 int ls=T[now].ls,rs=T[now].rs,lans=-INF,rans=-INF; 80 if (ls) lans=Get_Max(ls); 81 if (rs) rans=Get_Max(rs); 82 if (lans<rans) 83 { 84 if (lans>tmp1) Query_Max(ls); 85 if (rans>tmp1) Query_Max(rs); 86 } 87 else 88 { 89 if (rans>tmp1) Query_Max(rs); 90 if (lans>tmp1) Query_Max(ls); 91 } 92 } 93 void Query_Min(int now) 94 { 95 if (now!=LIM) tmp2=min(tmp2,abs(Q.d[0]-T[now].d[0])+abs(Q.d[1]-T[now].d[1])); 96 int ls=T[now].ls,rs=T[now].rs,lans=INF,rans=INF; 97 if (ls) lans=Get_Min(ls); 98 if (rs) rans=Get_Min(rs); 99 if (lans<rans) 100 { 101 if (lans<tmp2) Query_Min(ls); 102 if (rans<tmp2) Query_Min(rs); 103 } 104 else 105 { 106 if (rans<tmp2) Query_Min(rs); 107 if (lans<tmp2) Query_Min(ls); 108 } 109 } 110 }KDT; 111 112 int main() 113 { 114 scanf("%d",&n); 115 for (int i=1; i<=n; ++i) 116 scanf("%d%d",&p[i].d[0],&p[i].d[1]); 117 Root=KDT.Build(0,1,n); 118 for (int i=1; i<=n; ++i) 119 { 120 Q.d[0]=p[i].d[0]; Q.d[1]=p[i].d[1]; 121 LIM=i; 122 tmp1=-INF; tmp2=INF; 123 KDT.Query_Max(Root); 124 KDT.Query_Min(Root); 125 ans=min(ans,tmp1-tmp2); 126 } 127 printf("%d\n",ans); 128 }轉載于:https://www.cnblogs.com/refun/p/10151332.html
總結
以上是生活随笔為你收集整理的BZOJ1941:[SDOI2010]Hide and Seek(K-D Tree)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图数据库:AgensGraph
- 下一篇: Spring Boot(09)——使用S