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

猜你喜欢

转载自www.cnblogs.com/Fighting-sh/p/9898855.html