1. 程式人生 > >SJY擺棋子&&[Violet 3]天使玩偶

SJY擺棋子&&[Violet 3]天使玩偶

SJY擺棋子

https://www.lydsy.com/JudgeOnline/problem.php?id=2648

 [Violet 3]天使玩偶

https://www.lydsy.com/JudgeOnline/problem.php?id=2716

 

參考部落格:https://blog.csdn.net/Littlewhite520/article/details/78284697

 

KDtree模板題,帶插入

  1 #include<iostream>
  2 #include<cstring>
  3 #include<algorithm>
  4
#include<queue> 5 #include<string> 6 #include<cstdio> 7 #include<cmath> 8 #define MAXN 1000005 9 #define INF 0x3f3f3f3f 10 using namespace std; 11 12 int id; 13 int L,R,ans,root; 14 int n,m; 15 struct sair{ 16 int Max[2],Min[2],p[2],l,r; 17 bool operator<(const
sair &b)const{ 18 if(p[id]==b.p[id]) return p[id^1]<b.p[id^1]; 19 return p[id]<b.p[id]; 20 } 21 }tree[MAXN]; 22 23 int dist(int now){ 24 int dis=0;; 25 if(L<tree[now].Min[0]) dis+=tree[now].Min[0]-L; 26 if(L>tree[now].Max[0]) dis+=L-tree[now].Max[0
]; 27 if(R<tree[now].Min[1]) dis+=tree[now].Min[1]-R; 28 if(R>tree[now].Max[1]) dis+=R-tree[now].Max[1]; 29 return dis; 30 } 31 32 void pushup(int now){ 33 if(tree[now].l){ 34 if(tree[tree[now].l].Max[0]>tree[now].Max[0]) tree[now].Max[0]=tree[tree[now].l].Max[0]; 35 if(tree[tree[now].l].Min[0]<tree[now].Min[0]) tree[now].Min[0]=tree[tree[now].l].Min[0]; 36 if(tree[tree[now].l].Max[1]>tree[now].Max[1]) tree[now].Max[1]=tree[tree[now].l].Max[1]; 37 if(tree[tree[now].l].Min[1]<tree[now].Min[1]) tree[now].Min[1]=tree[tree[now].l].Min[1]; 38 } 39 if(tree[now].r){ 40 if(tree[tree[now].r].Max[0]>tree[now].Max[0]) tree[now].Max[0]=tree[tree[now].r].Max[0]; 41 if(tree[tree[now].r].Min[0]<tree[now].Min[0]) tree[now].Min[0]=tree[tree[now].r].Min[0]; 42 if(tree[tree[now].r].Max[1]>tree[now].Max[1]) tree[now].Max[1]=tree[tree[now].r].Max[1]; 43 if(tree[tree[now].r].Min[1]<tree[now].Min[1]) tree[now].Min[1]=tree[tree[now].r].Min[1]; 44 } 45 } 46 47 int build(int l,int r,int D){ 48 int mid=(l+r)>>1; 49 id=D; 50 nth_element(tree+l,tree+mid,tree+r+1); 51 if(l!=mid) tree[mid].l=build(l,mid-1,D^1); 52 if(r!=mid) tree[mid].r=build(mid+1,r,D^1); 53 tree[mid].Max[0]=tree[mid].Min[0]=tree[mid].p[0]; 54 tree[mid].Max[1]=tree[mid].Min[1]=tree[mid].p[1]; 55 pushup(mid); 56 return mid; 57 } 58 59 void Insert(int rt){ 60 int now=root,D=0;//now從頭開始往下查詢 61 while(1){ 62 ///比較新加進來的點,更新最大最小值 63 if(tree[rt].Max[0]>tree[now].Max[0]) tree[now].Max[0]=tree[rt].Max[0]; 64 if(tree[rt].Max[1]>tree[now].Max[1]) tree[now].Max[1]=tree[rt].Max[1]; 65 if(tree[rt].Min[0]<tree[now].Min[0]) tree[now].Min[0]=tree[rt].Min[0]; 66 if(tree[rt].Min[1]<tree[now].Min[1]) tree[now].Min[1]=tree[rt].Min[1]; 67 68 if(tree[rt].p[D]>=tree[now].p[D]){ 69 if(!tree[now].r){ 70 tree[now].r=rt; 71 return; 72 } 73 now=tree[now].r; 74 } 75 else{ 76 if(!tree[now].l){ 77 tree[now].l=rt; 78 return; 79 } 80 now=tree[now].l; 81 } 82 D^=1; 83 } 84 } 85 86 void query(int now){ 87 int dl,dr,dis; 88 dis=abs(tree[now].p[0]-L)+abs(tree[now].p[1]-R); 89 if(dis<ans) ans=dis; 90 if(tree[now].l) dl=dist(tree[now].l); 91 else dl=INF; 92 if(tree[now].r) dr=dist(tree[now].r); 93 else dr=INF; 94 if(dl<dr){ 95 if(dl<ans) query(tree[now].l); 96 if(dr<ans) query(tree[now].r); 97 } 98 else{ 99 if(dr<ans) query(tree[now].r); 100 if(dl<ans) query(tree[now].l); 101 } 102 } 103 104 int main(){ 105 scanf("%d %d",&n,&m); 106 for(int i=1;i<=n;i++){ 107 scanf("%d %d",&tree[i].p[0],&tree[i].p[1]); 108 } 109 root=build(1,n,0); 110 int x,y,z; 111 for(int i=1;i<=m;i++){ 112 scanf("%d %d %d",&x,&y,&z); 113 if(x==1){ 114 n++; 115 tree[n].Max[0]=tree[n].Min[0]=tree[n].p[0]=y; 116 tree[n].Max[1]=tree[n].Min[1]=tree[n].p[1]=z; 117 Insert(n); 118 } 119 else{ 120 ans=INF; 121 L=y,R=z; 122 query(root); 123 printf("%d\n",ans); 124 } 125 } 126 } 127 /* 128 2 3 129 1 1 130 2 3 131 2 1 2 132 1 3 3 133 2 4 2 134 */
View Code