【BZOJ】2648: SJY摆棋子 & 2716: [Violet 3]天使玩偶(kdtree)
http://www.lydsy.com/JudgeOnline/problem.php?id=2716
http://www.lydsy.com/JudgeOnline/problem.php?id=2648
双倍经验题。。。
kdtree裸题吧。。。。。今天学了下kdtree。。。感觉挺简单的。。。。
其实就是对几何图形进行剖分建树,而特殊在于,x和y轴轮流剖。。。。这样可以提供很好的性质以便于查找。。。
(一开始脑补了个treap代替kdtree。。。。。显然我脑残了。。。。写到一半发现这是不能旋转的。。。。。
(然后又脑补了下。。。。这货如果和孙子(儿子的儿子)可以旋转。。。。。。。。因为这货的节点类似红黑树。。。但是蒟蒻我太弱从来没写过红黑树。。。
很好的资料(概念脑补):http://www.cnblogs.com/v-July-v/archive/2012/11/20/3125419.html
一些参考代码(虽然说完全没按照这样写):http://blog.csdn.net/jiangshibiao/article/details/34144829
说一下怎么查找。
首先这是曼哈顿距离。。和欧几里得距离不同。。。如果欧几里得那么简单多了。。
我们需要维护极值(即能包围所有子树包括自己的点的一个矩形的四个顶点):
如果要查找的点在矩形内,那么进入查找。
如果在矩形外,那么计算出查找点到矩形的曼哈顿距离,判断是否小于当前最优解,如果是,进入搜索。
(或许还能优化,因为一开始我的想法和这个不怎么一样。。我觉得。。递归进入两棵子树中其中一棵后(按x或y排序而不是找极值),然后判断最优解是否能从左子树的某个点越过当前根的分割线。。。。。如果是,就进入。。。
然后就没了。。。
留下的坑:欧几里得的没写过。。。删除操作没写过(觉对要斯巴达。。。。想写成平衡树(强迫症系列
- #include <cstdio>
- #include <cstring>
- #include <cmath>
- #include <string>
- #include <iostream>
- #include <algorithm>
- #include <queue>
- #include <set>
- #include <map>
- using namespace std;
- typedef long long ll;
- #define rep(i, n) for(int i=0; i<(n); ++i)
- #define for1(i,a,n) for(int i=(a);i<=(n);++i)
- #define for2(i,a,n) for(int i=(a);i<(n);++i)
- #define for3(i,a,n) for(int i=(a);i>=(n);--i)
- #define for4(i,a,n) for(int i=(a);i>(n);--i)
- #define CC(i,a) memset(i,a,sizeof(i))
- #define read(a) a=getint()
- #define print(a) printf("%d", a)
- #define dbg(x) cout << (#x) << " = " << (x) << endl
- #define error(x) (!(x)?puts("error"):0)
- #define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next)
- inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
- const int N=2000005, oo=~0u>>1;
- struct node *null;
- struct node {
- node *c[2];
- int mx[2], mn[2], p[2];
- void upd(node *x) {
- if(x==null) return;
- mx[0]=max(mx[0], x->mx[0]);
- mx[1]=max(mx[1], x->mx[1]);
- mn[0]=min(mn[0], x->mn[0]);
- mn[1]=min(mn[1], x->mn[1]);
- }
- int getdis(node *x) {
- int ret=0;
- ret+=max(x->p[0]-mx[0], 0);
- ret+=max(x->p[1]-mx[1], 0);
- ret+=max(mn[0]-x->p[0], 0);
- ret+=max(mn[1]-x->p[1], 0);
- return ret;
- }
- void init(int x, int y) {
- p[0]=mx[0]=mn[0]=x;
- p[1]=mx[1]=mn[1]=y;
- c[0]=c[1]=null;
- }
- int dis(node *x) { return abs(p[0]-x->p[0])+abs(p[1]-x->p[1]); }
- }*root, T[N], *Tcnt=T;
- node *newnode(int x=0, int y=0) { Tcnt->init(x, y); return Tcnt++; }
- void init() { null=newnode(); null->c[0]=null->c[1]=null; root=null; }
- void insert(node *&x, node *y, bool f) {
- if(x==null) { x=y; return; }
- bool d=x->p[f]<y->p[f];
- x->upd(y);
- insert(x->c[d], y, !f);
- }
- void ins(int x, int y) { insert(root, newnode(x, y), 0); }
- void ask(node *x, node *y, int &ans) {
- ans=min(ans, x->dis(y));
- int d[2];
- d[0]=x->c[0]==null?oo:x->c[0]->getdis(y);
- d[1]=x->c[1]==null?oo:x->c[1]->getdis(y);
- bool f=d[0]>d[1]; if(d[f]==oo) return;
- ask(x->c[f], y, ans); if(d[!f]<ans) ask(x->c[!f], y, ans);
- }
- int ask(int x, int y) {
- int ret=oo; static node r;
- r.p[0]=x; r.p[1]=y;
- ask(root, &r, ret);
- return ret;
- }
- int main() {
- init();
- int n=getint(), m=getint();
- rep(i, n) { int x=getint(), y=getint(); ins(x, y); }
- while(m--) {
- int t=getint(), x=getint(), y=getint();
- if(t==2) printf("%d\n", ask(x, y));
- else ins(x, y);
- }
- return 0;
- }
Description
Input
Output
Sample Input
1 1
2 3
2 1 2
1 3 3
2 4 2
Sample Output
2
HINT
kdtree可以过
Source
【BZOJ】2648: SJY摆棋子 & 2716: [Violet 3]天使玩偶(kdtree)的更多相关文章
- bzoj 2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 --kdtree
2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 Time Limit: 20 Sec Memory Limit: 128 MB Description 这天,S ...
- BZOJ2648: SJY摆棋子&&2716: [Violet 3]天使玩偶
BZOJ2648: SJY摆棋子 BZOJ2716: [Violet 3]天使玩偶 BZOJ氪金无极限... 其实这两道是同一题. 附上2648的题面: Description 这天,SJY显得无聊. ...
- bzoj2648SJY摆棋子&&bzoj2716[Violet 3]天使玩偶*
bzoj2648SJY摆棋子 bzoj2716[Violet 3]天使玩偶 题意: 棋盘上有n个棋子,现在有m个操作,一种是加棋子,一种是查询离某个点最近的棋子.n,m≤500000. 题解: 先将已 ...
- 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摆棋子(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摆棋子(KD树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2716 [题目大意] 给出一些点,同时不断插入点和询问某点离插入点最近距离 [题解] 我 ...
随机推荐
- 关于DCMTK3.6.1源代码编译的总结
1.字符集不匹配 解决方法:更改Unicode字符集为多字节字符集 2.oflog.lib(winsock.obj) : error LNK2019: 无法解析的外部符号 错误. 解决方法:更改附加依 ...
- django 1.5+ 权限设计浅析
权限关系图 依赖app: django.contrib.auth django.contrib.contenttype admin后台的权限控制解析 (path/to/django.contrib.a ...
- poj1166
爆搜就可以过,不过我用了迭代加深. 注意每个操作最多进行4次 #include <cstdio> #include <cstdlib> using namespace std; ...
- codeforces 471C.MUH and House of Cards 解题报告
题目链接:http://codeforces.com/problemset/problem/471/C 题目意思:有 n 张卡,问能做成多少种不同楼层(floor)的 house,注意这 n 张卡都要 ...
- [SVN(ubuntu)] svn 文件状态标记含义
A item 文件.目录或是符号链item预定加入到版本库. C item 文件item发生冲突,在从服务器更新时与本地版本发生交迭,在你提交到版本库前,必须手工的解决冲突. D item 文件.目录 ...
- Android之Intent深入
Android中的意图包含多种用法,本文主要包括以下内容 显式意图 隐匿意图 要求结果回传的意图 显式意图 :必须指定要激活的组件的完整包名和类名 (应用程序之间耦合在一起) 一般激活自己应用的组件的 ...
- MySQL错误:Every derived table must have its own alias
Every derived table must have its own alias 派生表都必须有自己的别名 一般在多表查询时,会出现此错误. 因为,进行嵌套查询的时候子查询出来的的结果是作为一个 ...
- Web服务器原理及简单实现
Web系统由客户端(浏览器)和服务器端两部分组成.Web系统架构也被称为B/S架构.最常见的Web服务器有Apache.IIS等,常用的浏览器有IE.Firefox.chrome等.当你想访问一个网页 ...
- 计算字符串相似度算法——Levenshtein
转自:http://wdhdmx.iteye.com/blog/1343856 0.这个算法实现起来很简单 1.百度百科介绍: Levenshtein 距离,又称编辑距离,指的是两个字符串之间,由一个 ...
- VMWare Workstation的命令
1 Ctrl + Alt + <-/-> 多个操作系统的切换