2648: SJY摆棋子
2648: SJY摆棋子
https://www.lydsy.com/JudgeOnline/problem.php?id=2648
分析:
k-d tree 模板题。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for (;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ;
const int DIM = ;
const int INF = 1e9; #define lc T[rt].ch[0]
#define rc T[rt].ch[1] struct Point {
int x[];
Point() {x[] = ,x[] = ;}
Point(int a,int b) {x[] = a,x[] = b;}
}P[N];
struct KD_Tree {
int ch[],mn[],mx[];
Point p;
}T[N<<];
int Cur,CntNode,Ans,Root; inline bool cmp(Point a,Point b) {
return a.x[Cur] < b.x[Cur];
}
inline void pushup(int rt) {
for (int i=; i<DIM; ++i) {
if (lc) T[rt].mn[i] = min(T[rt].mn[i],T[lc].mn[i]), T[rt].mx[i] = max(T[rt].mx[i],T[lc].mx[i]);
if (rc) T[rt].mn[i] = min(T[rt].mn[i],T[rc].mn[i]), T[rt].mx[i] = max(T[rt].mx[i],T[rc].mx[i]); // -- rc - lc
}
}
inline void NewNode(int rt,Point p) {
T[rt].p = p;
T[rt].mn[] = T[rt].mx[] = p.x[];
T[rt].mn[] = T[rt].mx[] = p.x[];
}
int build(int l,int r,int cd) { // cd -- cur dimensions
if (l > r) return ;
int m = (l + r) >> ,rt = m;
Cur = cd; nth_element(P+l, P+m, P+r+, cmp);
NewNode(rt,P[m]);
lc = build(l, m-, cd^);
rc = build(m+, r, cd^);
pushup(rt);
return rt;
}
void Insert(Point p,int &rt,int cd) {
if (!rt) {
NewNode(rt = ++CntNode,p);return ;
}
if (p.x[cd] <= T[rt].p.x[cd]) Insert(p, lc, cd^);
else Insert(p, rc, cd^);
pushup(rt);
}
inline int dist(Point a,KD_Tree b) {
int dis = ;
if (a.x[] < b.mn[]) dis += b.mn[] - a.x[];
if (a.x[] > b.mx[]) dis += a.x[] - b.mx[];
if (a.x[] < b.mn[]) dis += b.mn[] - a.x[];
if (a.x[] > b.mx[]) dis += a.x[] - b.mx[];
return dis;
}
inline int dis(Point a,Point b) {
return abs(a.x[] - b.x[]) + abs(a.x[] - b.x[]);
}
void query(Point p,int rt) {
Ans = min(Ans,dis(p,T[rt].p)); // -- !!
int dl = lc ? dist(p,T[lc]) : INF;
int dr = rc ? dist(p,T[rc]) : INF;
if (dl < dr) {
if (dl < Ans) query(p,lc);
if (dr < Ans) query(p,rc);
}
else {
if (dr < Ans) query(p,rc);
if (dl < Ans) query(p,lc);
}
}
int main() {
int n = read(),m = read();
CntNode = n; // --- !!!
for (int i=; i<=n; ++i)
P[i].x[] = read(),P[i].x[] = read();
Root = build(,n,);
while (m--) {
int opt = read(),x = read(),y = read();
if (opt == ) Insert(Point(x,y),Root,);
else {
Ans = INF;
query(Point(x,y),Root);
printf("%d\n",Ans);
}
}
return ;
}
luogu上需要拍扁重构,否则会T,而bzoj上拍扁重构却不如不拍扁重构跑得快
#include<bits/stdc++.h>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for (;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ;
const int DIM = ;
const int INF = 1e9; #define alpha 0.75
#define lc T[rt].ch[0]
#define rc T[rt].ch[1] struct Point {
int x[];
Point() {x[] = ,x[] = ;}
Point(int a,int b) {x[] = a,x[] = b;}
}P[N<<];
struct KD_Tree {
int ch[],mn[],mx[],sz;
Point p;
}T[N<<];
int sk[N],Top,Cur,CntNode,Ans,Root; inline bool cmp(Point a,Point b) {
return a.x[Cur] < b.x[Cur];
}
inline void pushup(int rt) {
T[rt].sz = T[lc].sz + T[rc].sz + ; //-- +1!!!
for (int i=; i<DIM; ++i) {
if (lc) T[rt].mn[i] = min(T[rt].mn[i],T[lc].mn[i]), T[rt].mx[i] = max(T[rt].mx[i],T[lc].mx[i]);
if (rc) T[rt].mn[i] = min(T[rt].mn[i],T[rc].mn[i]), T[rt].mx[i] = max(T[rt].mx[i],T[rc].mx[i]);
}
}
inline void NewNode(int &rt,Point p) {
rt = Top ? sk[Top--] : ++CntNode;
T[rt].p = p;
T[rt].sz = ; // --!!!
T[rt].mn[] = T[rt].mx[] = p.x[];
T[rt].mn[] = T[rt].mx[] = p.x[];
}
int build(int l,int r,int cd) { // cd -- cur dimensions
if (l > r) return ;
int m = (l + r) >> ,rt;
Cur = cd; nth_element(P+l, P+m, P+r+, cmp);
NewNode(rt,P[m]);
lc = build(l, m-, cd^);
rc = build(m+, r, cd^);
pushup(rt);
return rt;
}
void dfs(int rt,int num) {
if (lc) dfs(lc, num);
P[num+T[lc].sz+] = T[rt].p, sk[++Top] = rt;
if (rc) dfs(rc, num+T[lc].sz+);
}
inline void check(int &rt,int cd) {
if (alpha * T[rt].sz < T[lc].sz || alpha * T[rt].sz < T[rc].sz) {
dfs(rt, );
rt = build(, T[rt].sz, cd);
}
}
void Insert(Point p,int &rt,int cd) {
if (!rt) {
NewNode(rt,p);return ;
}
if (p.x[cd] <= T[rt].p.x[cd]) Insert(p, lc, cd^);
else Insert(p, rc, cd^);
pushup(rt);check(rt,cd);
}
inline int dist(Point a,KD_Tree b) {
int dis = ;
if (a.x[] < b.mn[]) dis += b.mn[] - a.x[];
if (a.x[] > b.mx[]) dis += a.x[] - b.mx[];
if (a.x[] < b.mn[]) dis += b.mn[] - a.x[];
if (a.x[] > b.mx[]) dis += a.x[] - b.mx[];
return dis;
}
inline int dis(Point a,Point b) {
return abs(a.x[] - b.x[]) + abs(a.x[] - b.x[]);
}
void query(Point p,int rt) {
Ans = min(Ans,dis(p,T[rt].p)); // -- !!
int dl = lc ? dist(p,T[lc]) : INF;
int dr = rc ? dist(p,T[rc]) : INF;
if (dl < dr) {
if (dl < Ans) query(p,lc);
if (dr < Ans) query(p,rc);
}
else {
if (dr < Ans) query(p,rc);
if (dl < Ans) query(p,lc);
}
}
int main() {
int n = read(),m = read();
for (int i=; i<=n; ++i)
P[i].x[] = read(),P[i].x[] = read();
Root = build(,n,);
while (m--) {
int opt = read(),x = read(),y = read();
if (opt == ) Insert(Point(x,y),Root,);
else {
Ans = INF;
query(Point(x,y),Root);
printf("%d\n",Ans);
}
}
return ;
}
2648: SJY摆棋子的更多相关文章
- BZOJ 2648: SJY摆棋子
2648: SJY摆棋子 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2968 Solved: 1011[Submit][Status][Disc ...
- BZOJ 2648: SJY摆棋子 kdtree
2648: SJY摆棋子 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=2648 Description 这天,SJY显得无聊.在家自己玩 ...
- bzoj 2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 --kdtree
2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 Time Limit: 20 Sec Memory Limit: 128 MB Description 这天,S ...
- 【BZOJ】2648: SJY摆棋子 & 2716: [Violet 3]天使玩偶(kdtree)
http://www.lydsy.com/JudgeOnline/problem.php?id=2716 http://www.lydsy.com/JudgeOnline/problem.php?id ...
- BZOJ 2648: SJY摆棋子(K-D Tree)
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 6051 Solved: 2113[Submit][Status][Discuss] Descript ...
- bzoj 2648 SJY摆棋子 kd树
题目链接 初始的时候有一些棋子, 然后给两种操作, 一种是往上面放棋子. 另一种是给出一个棋子的位置, 问你离它最近的棋子的曼哈顿距离是多少. 写了指针版本的kd树, 感觉这个版本很好理解. #inc ...
- BZOJ 2648 SJY摆棋子(KD Tree)
http://www.lydsy.com/JudgeOnline/problem.php?id=2648 题意: 思路: KDtree模板题. 参考自http://www.cnblogs.com/ra ...
- bzoj 2648 SJY摆棋子——KDtree
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2648 第一道KDtree! 学习资料:https://blog.csdn.net/zhl30 ...
- bzoj 2648 SJY摆棋子 —— K-D树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2648 学习资料:https://blog.csdn.net/zhl30041839/arti ...
随机推荐
- 108. Convert Sorted Array to Binary Search Tree (building tree with resursion)
Given an array where elements are sorted in ascending order, convert it to a height balanced BST. Fo ...
- IOS VFL语言(页面布局)
● 什么是VFL语言 ● VFL全称是Visual Format Language,翻译过来是“可视化格式语言” ● VFL是苹果公司为了简化Autolayout的编码而推出的抽象语言 VFL ...
- Android进阶笔记10:ListView篇之ListView显示多种类型的条目(item)
ListView可以显示多种类型的条目布局,这里写显示两种布局的情况,其他类似. 1. 这是MainActivity,MainActivity的布局就是一个ListView,太简单了这里就不写了,直接 ...
- swift 协议(结合扩展)的特点
协议的传统实现: 定义接口+实现协议 由抽象到具体: 协议的逆向实现(使用扩展): 由已存在的类型抽离部分功能作为协议,并让原体符合协议: 由具体到抽象: 向上抽离: 向上生成: 协议的缺省 ...
- POJ 2771 Guardian of Decency 【最大独立集】
传送门:http://poj.org/problem?id=2771 Guardian of Decency Time Limit: 3000MS Memory Limit: 65536K Tot ...
- ms17_010利用复现(32位)
准备阶段: 1,原版windows7:cn_windows_7_enterprise_x86_dvd_x15-70737.iso 2,kali系统, 虚拟机 3,用于32位机的攻击模块:Eterna ...
- Android学习笔记_46_Android的intent之间Object、List、List<Object>和全局变量数据的传递(Parcelable Serializable)
转http://blog.csdn.net/pku_android/article/details/7456305 一.传递List<String>和List<Integer> ...
- c++ 虚基类应用
多重继承存在二义性,为了消除二义性在访问相同名称的属性时需要加上类名,加以区分.虽然这样可以解决二义性,但是相同的属性出现在多个基类中,为了解决数据冗余,c++引入了虚基类. 虚基类定义:class ...
- 【题解】洛谷P2341 [HAOI2006]受欢迎的牛(强连通分量)
洛谷P2341:https://www.luogu.org/problemnew/show/P2341 前言 这题看错题目 足足花了将近5小时提交了15次 在一位dalao的提醒下才AC了 记得要看清 ...
- IP地址获取当前地理位置(省份)的接口
腾讯的接口是 ,返回数组 http://fw.qq.com/ipaddress 返回值 var IPData = new Array("61.135.152.194"," ...