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 */

原文地址:https://www.cnblogs.com/Fighting-sh/p/9898855.html

时间: 2024-10-12 17:59:36

SJY摆棋子&&[Violet 3]天使玩偶的相关文章

【BZOJ-2648&amp;2716】SJY摆棋子&amp;天使玩偶 KD Tree

2648: SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2459  Solved: 834[Submit][Status][Discuss] Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子.此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) .现在给出N<=500000

BZOJ 2648: SJY摆棋子

Descrption 平面求最近点...\(n\leqslant 5\times 10^5\) Solution KD-Tree. 双倍经验..BZOJ 2716: [Violet 3]天使玩偶 Code /************************************************************** Problem: 2648 User: BeiYu Language: C++ Result: Accepted Time:13864 ms Memory:32560

BZOJ 2648(SJY摆棋子-KD_Tree)

2648: SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 1180  Solved: 391 [Submit][Status][Discuss] Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子.此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) .现在给出N<=5000

【BZOJ 2716/2648】 [Violet 3]天使玩偶

2716: [Violet 3]天使玩偶 kd-tree模板题. ①首先依次按照每一维(即先按照x,再按照y,再按照x-多维同理)将点存在一棵二叉树中: 先求出以当前维数为关键字的中间点是谁(用到nth_element这个函数,可以直接把排名为k的放在第k位上,不保证其他有序:nth_element(a+1,a+1+k,a+1+n,cmp)) 为了一会儿查询中求估价函数方便,需要记录一下当前节点的子树中各维的极值(max,min) ②插入操作与splay的插入操作同理. ③询问操作的本质是搜索+

【BZOJ2648】SJY摆棋子 [KD-tree]

SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子.此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) .现在给出N个初始棋子,和M个操作.对于每个白色棋子,输出距离这个白色棋子最近的黑色棋子的

BZOJ 2716: [Violet 3]天使玩偶

2716: [Violet 3]天使玩偶 Time Limit: 80 Sec  Memory Limit: 128 MBSubmit: 1473  Solved: 621[Submit][Status][Discuss] Description Input Output Sample Input & Output 样例过大,略 HINT Source Vani原创 欢迎移步 OJ2648 [Submit][Status][Discuss] CDQ分治,分类讨论拆绝对值的方式,分别查询最优值.

BZOJ 2648 SJY摆棋子 / 2716 Violet 3 天使玩偶 K-D树

题目大意:平面上有一些点,问一个点周围离它最近的点的曼哈顿距离是多少.支持动态加点. 思路:CDQ分治可以离线解决,但是SJY是卡CDQ的,天使玩偶可以过.毕竟K-D树的O(sqrt(n))的时间复杂度摆在那. K-D树理解起来其实不难,有k个维度的时候,每一层按照一个维度排序,取出按照这个维度排序的中位数,当作这个块的根,然后将这个块分开.还有一个比较重要的东西就是估价函数,这个函数根据不同的题可能不同.股价函数的主要用途就是对搜索进行剪枝,如果估价函数就已经大于当前的最优答案了,那就不用搜这

[Violet]天使玩偶/SJY摆棋子

Luogu4169 每次操作加入平面上一个点 , 或者询问离一个点最近的点的距离 CDQ分治模板 \(1.\)solve(l,mid); \(2.\)solve(mid+1,r); \(3.\)计算\([l,mid]\)中修改操作对\([mid+1,r]\)中查询操作的影响 /* ---------------------- [CDQ分治] 天使玩偶 1.solve(l,mid); 2.solve(mid+1,r); 3.计算[l,mid]中修改操作对[mid+1,r]中查询操作的影响 ----

【bzoj 2716】[Violet 3]天使玩偶 (CDQ+树状数组)

题目描述 Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里,所以她决定仅凭一点模糊的记忆来寻找它. 我们把 Ayu 生活的小镇看作一个二维平面坐标系,而 Ayu 会不定时地记起可能在某个点 (xmy) 埋下了天使玩偶:或者 Ayu 会询问你,假如她在 (x,y) ,那么她离近的天使玩偶可能埋下的地方有多远. 因为 Ayu 只会沿着平行坐标轴的方向来行动,所以在这个问题里我们定义两个点之间的距离为dist(A,B)=|A