BZOJ 2648/2716 SJY摆棋子/[Violet 3]天使玩偶 kd tree

本文介绍了一个关于KDT树的应用案例,通过解决一个具体问题来详细解释KDT树的工作原理及其实现过程。文章中不仅提供了完整的代码实现,还对代码进行了详细的注释说明。

Description

这天,SJY显得无聊。在家自己玩。在一个棋盘上,有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子。此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) 。现在给出N<=500000个初始棋子。和M<=500000个操作。对于每个白色棋子,输出距离这个白色棋子最近的黑色棋子的距离。同一个格子可能有多个棋子。
 

Input

第一行两个数 N M
以后M行,每行3个数 t x y
如果t=1 那么放下一个黑色棋子
如果t=2 那么放下一个白色棋子

Output

对于每个T=2 输出一个最小距离
 

Sample Input

2 3
1 1
2 3
2 1 2
1 3 3
2 4 2

Sample Output


1
2

HINT

 

kdtree可以过






双倍经验hhh
此题似乎是kdtree的裸题= =
询问最坏是O(根号n)的,
就是插入可能最坏会O(n)吧,不行可以重构……但是其实还是会T的感觉。。

一开始网上很多题解的曼哈顿距离记录了max,min啥的不是很明白。
现在感觉就是一个启发式搜索。
维护当前切割的平面里面的二维坐标的最值,共4个。
然后搜索答案的时候可以判断两个平面内的dist,然后启发式地走哪一边。
感觉有点说不大清楚……max,min就是维护某一个切割平面内的坐标的最值。
画个图会更加明显一点的。

代码部分我不太行……
借鉴了orz 的代码。
调着调着就几乎和他一样了……(笑哭)

卡常?不存在的= =



#include<bits/stdc++.h>
#define ll long long
using namespace std;
int read(){
    int x=0,f=1;char ch=getchar();
    while (ch<'0' || ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int 
	N=500005,
	inf=2000000000;
int n,m,t,ans,root;
struct POINT{
	int Dim[2],MAX[2],MIN[2],l,r;
}point[N+N],T;
bool cmp(POINT x,POINT y){
	return x.Dim[t]<y.Dim[t];
}
int dist(int u,int x,int y){
	int dis=0;
	if (x<point[u].MIN[0]) dis+=point[u].MIN[0]-x;
	if (x>point[u].MAX[0]) dis+=x-point[u].MAX[0];
	if (y<point[u].MIN[1]) dis+=point[u].MIN[1]-y;
	if (y>point[u].MAX[1]) dis+=y-point[u].MAX[1];
	return dis;
}
void up(int u){
	if (point[u].l){
		point[u].MAX[0]=max(point[u].MAX[0],point[point[u].l].MAX[0]);
		point[u].MAX[1]=max(point[u].MAX[1],point[point[u].l].MAX[1]);
		point[u].MIN[0]=min(point[u].MIN[0],point[point[u].l].MIN[0]);
		point[u].MIN[1]=min(point[u].MIN[1],point[point[u].l].MIN[1]);
	}
	if (point[u].r){
		point[u].MAX[0]=max(point[u].MAX[0],point[point[u].r].MAX[0]);
		point[u].MAX[1]=max(point[u].MAX[1],point[point[u].r].MAX[1]);
		point[u].MIN[0]=min(point[u].MIN[0],point[point[u].r].MIN[0]);
		point[u].MIN[1]=min(point[u].MIN[1],point[point[u].r].MIN[1]);
	}
}
int build(int L,int R,int now){
	int mid=(L+R)>>1;t=now;
	nth_element(point+L,point+mid,point+R+1,cmp);
	point[mid].MAX[0]=point[mid].MIN[0]=point[mid].Dim[0];
	point[mid].MAX[1]=point[mid].MIN[1]=point[mid].Dim[1];
	if (L!=mid) point[mid].l=build(L,mid-1,now^1);
	if (R!=mid) point[mid].r=build(mid+1,R,now^1);
	up(mid);
	return mid;
}
void insert(int id){
	int now=0,p=root;
	while (1){
		point[p].MAX[0]=max(point[id].MAX[0],point[p].MAX[0]);
		point[p].MAX[1]=max(point[id].MAX[1],point[p].MAX[1]);
		point[p].MIN[0]=min(point[id].MIN[0],point[p].MIN[0]);
		point[p].MIN[1]=min(point[id].MIN[1],point[p].MIN[1]);
		if (point[id].Dim[now]<=point[p].Dim[now])
			if (!point[p].l){
				point[p].l=id;
				return;
			} else p=point[p].l;
		 else if (!point[p].r){
				point[p].r=id;
				return;
			} else p=point[p].r;
		now^=1;
	}
}
void query(int id){
	int d0,dl,dr;
	d0=abs(T.Dim[0]-point[id].Dim[0])+abs(T.Dim[1]-point[id].Dim[1]);
	if (ans>d0) ans=d0;
	if (point[id].l) dl=dist(point[id].l,T.Dim[0],T.Dim[1]); else dl=inf;
	if (point[id].r) dr=dist(point[id].r,T.Dim[0],T.Dim[1]); else dr=inf;
	if (dl<dr){
		if (dl<ans) query(point[id].l);
		if (dr<ans) query(point[id].r);
	} else{
		if (dr<ans) query(point[id].r);
		if (dl<ans) query(point[id].l);
	}
}
int main(){
	n=read(),m=read();
	for (int i=1;i<=n;i++)
		point[i].Dim[0]=read(),point[i].Dim[1]=read();
	root=build(1,n,0);
	while (m--){
		int opt=read();
		T.Dim[0]=read(),T.Dim[1]=read();
		if (opt==1){
			n++;
			point[n].MAX[0]=point[n].MIN[0]=point[n].Dim[0]=T.Dim[0];
			point[n].MAX[1]=point[n].MIN[1]=point[n].Dim[1]=T.Dim[1];
			insert(n);
		} else{
			ans=inf,query(root);
			printf("%d\n",ans);
		}
	}
	return 0;
}

内容概要:本文围绕可变桨叶四旋翼无人机的规范控制与点对点运动模拟展开,重点研究优化推力分配策略在翻转动作中的应用与性能比较。通过Matlab代码实现,构建了四旋翼动力学模型,并设计了多种控制算法以实现精确的姿态调整与轨迹跟踪。研究对比了不同推力分配方案在执行高机动性翻转动作时的稳定性、能耗效率与响应速度,旨在提升无人机在复杂飞行任务中的动态性能与控制精度。该仿真研究为无人机飞控系统的设计与优化提供了理论依据和技术支持。; 适合人群:具备一定自动控制理论基础和Matlab编程能力,从事无人机控制、飞行器动力学或机器人系统研究的科研人员及研究生。; 使用场景及目标:① 实现四旋翼无人机在三维空间中的精确点对点运动控制;② 对比分析不同推力分配策略在执行翻转等高难度动作时的控制效果与能耗表现,优化飞行性能;③ 为无人机自主飞行、特技飞行及复杂环境下的机动控制提供算法验证平台。; 阅读建议:此资源以Matlab仿真为核心,建议读者结合相关控制理论知识,深入理解代码实现细节,重点关注动力学建模、控制律设计与推力分配模块。在学习过程中,应动手调试参数,复现文中翻转动作的仿真结果,并尝试拓展至其他复杂飞行任务,以加深对无人机控制机理的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值