luogu4169 [Violet]天使玩偶/SJY摆棋子 / bzoj2648 SJY摆棋子 k-d tree
k-d tree + 重构的思想,就能卡过luogu和bzoj啦orz
#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std;
int n, m, rot, nowD, opt, uu, vv, ans, rub[1000005], din, cur;
const double aph=0.65;
struct Point{
int d[2], mn[2], mx[2], l, r, siz;
int & operator[](int x){
return d[x];
}
bool operator<(const Point &x)const{
return d[nowD]<x.d[nowD];
}
Point(int x=0, int y=0){
l = r = siz = 0;
d[0] = x; d[1] = y;
}
}p[1000005];
int getDis(Point x, Point y){
return abs(x[1]-y[1])+abs(x[0]-y[0]);
}
struct KDTree{
Point t[1000005], T;
void pushUp(int x){
Point l=t[t[x].l], r=t[t[x].r];
for(int i=0; i<2; i++){
t[x].mn[i] = t[x].mx[i] = t[x][i];
if(t[x].l){
t[x].mn[i] = min(t[x].mn[i], l.mn[i]);
t[x].mx[i] = max(t[x].mx[i], l.mx[i]);
}
if(t[x].r){
t[x].mn[i] = min(t[x].mn[i], r.mn[i]);
t[x].mx[i] = max(t[x].mx[i], r.mx[i]);
}
}
t[x].siz = l.siz + r.siz + 1;
}
int newNode(){
if(din) return rub[din--];
else return ++cur;
}
int build(int l, int r, int now){
nowD = now;
int mid=(l+r)>>1, k=newNode();
nth_element(p+l, p+mid, p+1+r);
t[k] = p[mid];
t[k].l = t[k].r = t[k].siz = 0;
if(l<mid) t[k].l = build(l, mid-1, now^1);
if(mid<r) t[k].r = build(mid+1, r, now^1);
pushUp(k);
return k;
}
void pia(int k, int num){
if(t[k].l) pia(t[k].l, num);
p[num+t[t[k].l].siz+1] = t[k];
rub[++din] = k;
if(t[k].r) pia(t[k].r, num+t[t[k].l].siz+1);
}
void chkPia(int &k, int now){
if(aph*t[k].siz<t[t[k].l].siz || aph*t[k].siz<t[t[k].r].siz){
pia(k, 0);
k = build(1, t[k].siz, now);
}
}
void insert(int &k, int now){
if(!k){
k = newNode();
t[k] = T;
t[k].l = t[k].r = 0;
pushUp(k);
return ;
}
if(T[now]>=t[k][now]) insert(t[k].r, now^1);
else insert(t[k].l, now^1);
pushUp(k);
chkPia(k, now);
}
int get(int k, Point p){
int re=0;
for(int i=0; i<2; i++)
re += max(0, p[i]-t[k].mx[i]);
for(int i=0; i<2; i++)
re += max(0, t[k].mn[i]-p[i]);
return re;
}
void query(int k, int now){
int d=getDis(t[k],T), dl=0x3f3f3f3f, dr=0x3f3f3f3f;
ans = min(ans, d);
if(t[k].l) dl = get(t[k].l, T);
if(t[k].r) dr = get(t[k].r, T);
if(dl<dr){
if(dl<ans) query(t[k].l, now^1);
if(dr<ans) query(t[k].r, now^1);
}
else{
if(dr<ans) query(t[k].r, now^1);
if(dl<ans) query(t[k].l, now^1);
}
}
}kdt;
void rn(int &x){
char ch=getchar();
x = 0;
while(ch<'0' || ch>'9') ch = getchar();
while(ch>='0' && ch<='9'){
x = x * 10 + ch - '0';
ch = getchar();
}
}
int main(){
cin>>n>>m;
for(int i=1; i<=n; i++){
rn(p[i][0]);
rn(p[i][1]);
}
rot = kdt.build(1, n, 0);
while(m--){
scanf("%d %d %d", &opt, &uu, &vv);
kdt.T = Point(uu, vv);
if(opt==1)
kdt.insert(rot, 0);
else{
ans = 0x3f3f3f3f;
kdt.query(rot, 0);
printf("%d\n", ans);
}
}
return 0;
}
luogu4169 [Violet]天使玩偶/SJY摆棋子 / bzoj2648 SJY摆棋子 k-d tree的更多相关文章
- [Luogu4169][Violet]天使玩偶/SJY摆棋子
luogu 题意 一个平面上有\(n\)个点,\(m\)次操作,每次新增一个点,或者是询问离某个点最近的点的距离.这里的距离是曼哈顿距离. \(n,m\le3*10^5\) sol 写一发\(CDQ\ ...
- bzoj2716/2648 / P4169 [Violet]天使玩偶/SJY摆棋子
P4169 [Violet]天使玩偶/SJY摆棋子 k-d tree 模板 找了好几天才发现输出优化错了....真是zz...... 当子树非常不平衡时,就用替罪羊树的思想,拍扁重建. luogu有个 ...
- 【LG4169】[Violet]天使玩偶/SJY摆棋子
[LG4169][Violet]天使玩偶/SJY摆棋子 题面 洛谷 题解 至于\(cdq\)分治的解法,以前写过 \(kdTree\)的解法好像还\(sb\)一些 就是记一下子树的横.纵坐标最值然后求 ...
- 洛谷 P4169 [Violet]天使玩偶/SJY摆棋子 解题报告
P4169 [Violet]天使玩偶/SJY摆棋子 题目描述 \(Ayu\)在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,\(Ayu\) 却忘了她把天使玩偶埋在了哪 ...
- luoguP4169 [Violet]天使玩偶/SJY摆棋子 K-Dtree
P4169 [Violet]天使玩偶/SJY摆棋子 链接 luogu 思路 luogu以前用CDQ一直过不去. bzoj还是卡时过去的. 今天终于用k-dtree给过了. 代码 #include &l ...
- 洛谷P4169 [Violet]天使玩偶/SJY摆棋子(CDQ分治)
[Violet]天使玩偶/SJY摆棋子 题目传送门 解题思路 用CDQ分治开了氧气跑过. 将输入给的顺序作为第一维的时间,x为第二维,y为第三维.对于距离一个询问(ax,ay),将询问分为四块,左上, ...
- [Violet]天使玩偶/SJY摆棋子 [cdq分治]
P4169 [Violet]天使玩偶/SJY摆棋子 求离 \((x,y)\) 最近点的距离 距离的定义是 \(|x1-x2|+|y1-y2|\) 直接cdq 4次 考虑左上右上左下右下就可以了-略微卡 ...
- BZOJ2648/2716:SJY摆棋子/[Violet]天使玩偶(K-D Tree)
Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子. ...
- P4169 [Violet]天使玩偶/SJY摆棋子
题目背景 感谢@浮尘ii 提供的一组hack数据 题目描述 Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里,所以她决定仅 ...
随机推荐
- 从零开始的全栈工程师——js篇2.5
数据类型与全局属性 js的本质就是处理数据 数据来自于后台的数据库所以变量就起到一个临时存储数据的这作用ECMAscirpt 制定了js的数据类型 一.数据类型 1.基本数据类型 基本数据类型就是简单 ...
- JVM(二):垃圾回收
三个问题: 那些内存需要回收? -- 对象是否存活判断 什么时候回收? --垃圾回收触发条件 如何回收? --垃圾回收算法 垃圾回收应用 -- 理解GC日志.使用垃圾回收命令和工具 1. 判断 ...
- HTTP响应报文与工作原理详解(转)
超文本传输协议(Hypertext Transfer Protocol,简称HTTP)是应用层协议.HTTP 是一种请求/响应式的协议,即一个客户端与服务器建立连接后,向服务器发送一个请求;服务器接到 ...
- CSS单词换行and断词,你真的完全了解吗
背景 某天老板在群里反馈,英文单词为什么被截断了? 很显然,这是我们前端的锅,自行背锅.这个问题太简单了,css里加两行属性,分分钟搞定. 开心的提交代码,刷新页面.我擦,怎么还是没有断词?不可能啊! ...
- 运用CSS3媒体查询判断iPhoneX、iPhoneXR、iPhoneXS MAX及横竖屏
//iphoneX.iphoneXs @media only screen and (device-width: 375px) and (device-height: 812px) and (-web ...
- 修改Oracle环境变量$PATH
此次在创建公司的Oracle 标准化应用时,提到了添加$PATH,但没有发现对我很符合我的现况的方法,现记录下此次添加$PATH的方法: 首先查看$PATH中是否已存在我们需要的路径: 执行指令ech ...
- nginx 中 root和alias
根本区别 一个请求的url= http://ip:port/path 在location中配置root和alias的区别: root是在location的正则之前拼接了路径 alias是在locati ...
- Coursera 算法二 week 3 Baseball Elimination
这周的作业不需要自己写算法,只需要调用库函数就行,但是有些难以理解,因此用了不少时间. import edu.princeton.cs.algs4.FlowEdge; import edu.princ ...
- java Vamei快速教程07 包
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们已经写了一些Java程序.之前的每个Java程序都被保存为一个文件,比如Tes ...
- 2018.5.18 AndroidStudio创建项目出错
Android Studio 出现 Gradle's dependency cache may be corrupt 错误分析 Error:Failed to open zip file. Gradl ...