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摆棋子的更多相关文章

  1. BZOJ 2648: SJY摆棋子

    2648: SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2968  Solved: 1011[Submit][Status][Disc ...

  2. BZOJ 2648: SJY摆棋子 kdtree

    2648: SJY摆棋子 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=2648 Description 这天,SJY显得无聊.在家自己玩 ...

  3. bzoj 2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 --kdtree

    2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 Time Limit: 20 Sec  Memory Limit: 128 MB Description 这天,S ...

  4. 【BZOJ】2648: SJY摆棋子 & 2716: [Violet 3]天使玩偶(kdtree)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2716 http://www.lydsy.com/JudgeOnline/problem.php?id ...

  5. BZOJ 2648: SJY摆棋子(K-D Tree)

    Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 6051  Solved: 2113[Submit][Status][Discuss] Descript ...

  6. bzoj 2648 SJY摆棋子 kd树

    题目链接 初始的时候有一些棋子, 然后给两种操作, 一种是往上面放棋子. 另一种是给出一个棋子的位置, 问你离它最近的棋子的曼哈顿距离是多少. 写了指针版本的kd树, 感觉这个版本很好理解. #inc ...

  7. BZOJ 2648 SJY摆棋子(KD Tree)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2648 题意: 思路: KDtree模板题. 参考自http://www.cnblogs.com/ra ...

  8. bzoj 2648 SJY摆棋子——KDtree

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2648 第一道KDtree! 学习资料:https://blog.csdn.net/zhl30 ...

  9. bzoj 2648 SJY摆棋子 —— K-D树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2648 学习资料:https://blog.csdn.net/zhl30041839/arti ...

随机推荐

  1. Perl 基础笔记: 使用 cpanm 安装 Perl 模块

    cpanm 其实只是一个可执行文件而已.将它下载到 bin 目录,然后添加执行权限就可以用了. $ sudo wget http://xrl.us/cpanm -O /usr/bin/cpanm; s ...

  2. One Order行项目里Item Category是怎么计算出来的

    One Order的行项目里有个字段叫Item Category,我们在行项目里加入一个product后,就会自动带出Item Category来.这个值是怎么计算出来的? 检查CRMD_ORDERA ...

  3. 每天一个linux命令:du 命令

    Linux du命令也是查看使用空间的,但是与df命令不同的是Linux du命令是对文件和目录磁盘使用的空间的查看,还是和df命令有一些区别的. 1.命令格式: du [选项][文件] 2.命令功能 ...

  4. CF498D Traffic Jams in the Land

    嘟嘟嘟 题面:有n条公路一次连接着n + 1个城市,每一条公路有一个堵塞时刻a[i],如果当前时间能被a[i]整除,那么通过这条公路需要2分钟:否则需要1分钟. 现给出n条公路的a[i],以及m次操作 ...

  5. 使用paramiko的问题记录

    用paramiko时遇到问题,异常如下: 解决方法记录如下: 更新gmp版本: wget https://ftp.gnu.org/gnu/gmp/gmp-6.0.0a.tar.bz2 tar -xvj ...

  6. SQL Server的Bug

    SQL 语句如下: SELECT * FROM Production.Product WHERE ProductNumber IN(SELECT ProductNumber FROM HumanRes ...

  7. Python基础—04-流程控制

    流程控制 循环结构(while) 格式 while 表达式: 语句块 执行流程:当程序执行到while语句时,首先判断表达式的真假.若表达式的值为真,则执行对应的语句块,之后返回while继续判断表达 ...

  8. html5语义化标签——回顾

    html5 头部结构   <!doctype html>    <meta charset=“utf-8”/> <header></header> 页眉 ...

  9. Vue--- VueX基础 (Vuex结构图数据流向)1.1

    Vuex基础 https://vuex.vuejs.org/zh-cn state --> view --> action -> state 多组件共享状态, 之前操作方式,由父组件 ...

  10. JDBC编程:使用 Statement 修改数据库

    获取数据连接后,即可对数据库中的数据进行修改和查看.使用 Statement 接口可以对数据库中的数据进行修改,下面是程序演示. /** * 获取数据库连接,并使用SQL语句,向数据库中插入记录 */ ...