BZOJ2648/2716:SJY摆棋子/[Violet]天使玩偶(K-D Tree)
Description
Input
Output
Sample Input
1 1
2 3
2 1 2
1 3 3
2 4 2
Sample Output
1
2
Solution
K-D Tree模板题,注意不替罪羊重构的话会TLE
Code
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#define N (1000000+1000)
#define INF 0x7fffffff
using namespace std; int n,m,D,ans,opt,x,y,Root;
double alpha=0.75; struct Node
{
int d[],Max[],Min[],lson,rson,size;
bool operator < (const Node &a) const {return d[D]<a.d[D];}
Node (int x=,int y=)
{
lson=rson=; d[]=x; d[]=y;;
Max[]=Min[]=d[];
Max[]=Min[]=d[];
}
}p[N],T; int stack[N],cnt,top;
int NewNode()
{
if (top) return stack[top--];
return ++cnt;
} struct KDT
{
Node Tree[N]; void Update(int now)
{
int ls=Tree[now].lson,rs=Tree[now].rson;
for (int i=; i<=; ++i)
{
Tree[now].Max[i]=Tree[now].Min[i]=Tree[now].d[i];
if (ls)
{
Tree[now].Max[i]=max(Tree[now].Max[i],Tree[ls].Max[i]);
Tree[now].Min[i]=min(Tree[now].Min[i],Tree[ls].Min[i]);
}
if (rs)
{
Tree[now].Max[i]=max(Tree[now].Max[i],Tree[rs].Max[i]);
Tree[now].Min[i]=min(Tree[now].Min[i],Tree[rs].Min[i]);
}
}
Tree[now].size=Tree[ls].size+Tree[rs].size+;
}
int Build(int opt,int l,int r)
{
if (l>r) return ;
int mid=(l+r)>>,now=NewNode();
D=opt; nth_element(p+l,p+mid,p+r+);
Tree[now]=p[mid]; Tree[now].size=;
Tree[now].lson=Build(opt^,l,mid-);
Tree[now].rson=Build(opt^,mid+,r);
Update(now);
return now;
}
int Get_min(int now)
{
int ans=;
for (int i=; i<=; ++i)
{
ans+=max(,T.d[i]-Tree[now].Max[i]);
ans+=max(,Tree[now].Min[i]-T.d[i]);
}
return ans;
}
void Query(int now)
{
ans=min(ans,abs(T.d[]-Tree[now].d[])+abs(T.d[]-Tree[now].d[]));
int ls=Tree[now].lson,rs=Tree[now].rson,lans=INF,rans=INF;
if (ls) lans=Get_min(ls);
if (rs) rans=Get_min(rs);
if (lans<rans)
{
if (lans<ans) Query(ls);
if (rans<ans) Query(rs);
}
else
{
if (rans<ans) Query(rs);
if (lans<ans) Query(ls);
}
}
void Dfs(int now,int sz)
{
int ls=Tree[now].lson,rs=Tree[now].rson;
if (ls) Dfs(ls,sz);
p[sz+Tree[ls].size]=Tree[now];
stack[++top]=now;
if (rs) Dfs(rs,sz+Tree[ls].size+);
}
void Check(int &now,int opt)
{
int ls=Tree[now].lson, rs=Tree[now].rson;
if (Tree[ls].size>alpha*Tree[now].size || Tree[rs].size>alpha*Tree[now].size)
{
Dfs(now,);
now=Build(opt,,Tree[now].size);
}
}
void Insert(int &now,int x,int opt)
{
if (Tree[x].d[opt]<=Tree[now].d[opt])
{
if (Tree[now].lson) Insert(Tree[now].lson,x,opt^);
else Tree[now].lson=x;
}
else
{
if (Tree[now].rson) Insert(Tree[now].rson,x,opt^);
else Tree[now].rson=x;
}
Update(now); Check(now,opt);
}
}KDT; int main()
{
scanf("%d%d",&n,&m);
for (int i=; i<=n; ++i)
{
scanf("%d%d",&x,&y);
p[i].d[]=x; p[i].d[]=y;
}
Root=KDT.Build(,,n);
for (int i=; i<=m; ++i)
{
scanf("%d%d%d",&opt,&x,&y);
if (opt==)
{
int t=NewNode();
KDT.Tree[t]=Node(x,y);
KDT.Tree[t].size=;
KDT.Insert(Root,t,);
}
else
{
T.d[]=x; T.d[]=y; ans=INF;
KDT.Query(Root);
printf("%d\n",ans);
}
}
}
BZOJ2648/2716:SJY摆棋子/[Violet]天使玩偶(K-D Tree)的更多相关文章
- [bzoj2648/2716]SJY摆棋子_KD-Tree
SJY摆旗子 bzoj-2648 题目大意:平面上有n个黑子.有m个操作,可以下一颗白子,查询与曼哈顿距离下最近黑子之间的曼哈顿距离,或者下一颗黑子. 注释:$1\le n,m\le 5\cdot 1 ...
- [bzoj2648/2716]SJY摆棋子
平面上有n个点,要求支持插入一个点和查询一个点的最近点距离 n,m<=500000 用kdtree实现,但是复杂度貌似没法保证.....(莫名加了替罪羊重建更慢了...) #include< ...
- 【BZOJ2648】SJY摆棋子(KD-Tree)
[BZOJ2648]SJY摆棋子(KD-Tree) 题面 BZOJ Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一 ...
- 【BZOJ2648】SJY摆棋子 KDtree
[BZOJ2648]SJY摆棋子 Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找 ...
- SJY摆棋子&&[Violet 3]天使玩偶
SJY摆棋子 https://www.lydsy.com/JudgeOnline/problem.php?id=2648 [Violet 3]天使玩偶 https://www.lydsy.com/Ju ...
- 【BZOJ2648】SJY摆棋子 [KD-tree]
SJY摆棋子 Time Limit: 20 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 这天,SJY显得无聊.在家自己 ...
- 【bzoj2648】 SJY摆棋子
http://www.lydsy.com/JudgeOnline/problem.php?id=2648 (题目链接) 题意 动态维护二维平面上的点的插入以及最邻近域搜索. Solution KDtr ...
- 【BZOJ2648】SJY摆棋子
题目大意:维护一个二维平面,平面上初始有 N 个点,支持两种操作:平面加点.查询距离某个指定点的最小哈密顿距离. 题解:学习到了 kd-tree 数据结构. kd-tree 类似于平衡树,即:每个节点 ...
- BZOJ2648:SJY摆棋子
浅谈\(K-D\) \(Tree\):https://www.cnblogs.com/AKMer/p/10387266.html 题目传送门:https://lydsy.com/JudgeOnline ...
随机推荐
- 转 C#对多个集合和数组的操作(合并,去重,判断)
在开发过程中.数组和集合的处理是最让我们担心.一般会用for or foreach 来处理一些操作.这里介绍一些常用的集合跟数组的操作函数. 首先举例2个集合A,B. List<int> ...
- js动态实现时分秒
<div id="time" style="color: #96C2DD;</div> <script type="text/ ...
- jacob自己动生成word文档目录
任务目的 1自动生成word文档目录. 用例测试操作步骤 在一个word文档的第二页填写占位符: {目录}保存.调用程序读取目标文档,自动根据标题生成目录到{目录}位置. 效果 关键代码 insert ...
- js 判断各种数据类型 typeof 几种类型值
了解js的都知道, 有个typeof 用来判断各种数据类型,有两种写法:typeof xxx ,typeof(xxx) 如下实例: typeof 2 输出 number ...
- express遇到的问题
1. 如何引入express? cnpm install express --save 其中--save可以保存到依赖项中. 接着 var express = require("expres ...
- js动画实现&&回调地狱&&promise
1. js实现动画 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- 使用 GitHub API 进行数据分析 (Node.js)
使用 GitHub API 进行数据分析 (Node.js) Node.js 的访问 GitHub 的 API 库,通过 npm 或者 yarn 安装: yarn add github-api 官方示 ...
- 【linux相识相知】sed命令
在之前的博客中我们介绍了文本三剑客中grep,本次博客就另外一名剑客——sed做出详细的描述,sed真的是一款强大的工具.下面让我们来一起看一下吧! 概述和工作机制 SED的英文全称为Stream E ...
- node.js获取cookie
node.js 获取cookie var Cookies ={}; if (req.headers.cookie != null) { req.headers.cookie.split(';').fo ...
- 【实用类String】String类方法的应用案例:查找判断指定字符出现的次数和位置
一.应用要求 输入一个字符串,再输入要查找的字符,判断该字符在该字符串中出现的次数. 二.实现思路 1.使用substring()方法将字符串的每个字符存入数组 2.比较数组每个字符是否与指定的字符相 ...