k-d tree模板练习
1. [BZOJ]1941: [Sdoi2010]Hide and Seek
题目大意:给出n个二维平面上的点,一个点的权值是它到其他点的最长距离减最短距离,距离为曼哈顿距离,求最小权值。(n<=500,000)
思路:k-d tree裸题。
#include<cstdio>
#include<algorithm>
using namespace std;
inline int read()
{
int x;char c;
while((c=getchar())<''||c>'');
for(x=c-'';(c=getchar())>=''&&c<='';)x=(x<<)+(x<<)+c-'';
return x;
}
#define MN 500000
#define INF 0x7FFFFFFF
int rt,D,q[];
struct node
{
int p[],mn[],mx[],l,r;
friend bool operator<(const node&a,const node&b){return a.p[D]<b.p[D];}
}t[MN+];
void up(int k)
{
for(int l=t[k].l,r=t[k].r,i=;i<;++i)
t[k].mn[i]=t[k].mx[i]=t[k].p[i],
l?(t[k].mn[i]=min(t[k].mn[i],t[l].mn[i]),t[k].mx[i]=max(t[k].mx[i],t[l].mx[i])):,
r?(t[k].mn[i]=min(t[k].mn[i],t[r].mn[i]),t[k].mx[i]=max(t[k].mx[i],t[r].mx[i])):;
}
int build(int l,int r)
{
if(l>r)return ;
int mid=l+r>>;D^=;
nth_element(t+l,t+mid,t+r+);
t[mid].l=build(l,mid-);
t[mid].r=build(mid+,r);
return D^=,up(mid),mid;
}
inline int calmx(int k)
{
return max(abs(q[]-t[k].mn[]),abs(t[k].mx[]-q[]))+
max(abs(q[]-t[k].mn[]),abs(t[k].mx[]-q[]));
}
void qmx(int k)
{
D=max(D,abs(t[k].p[]-q[])+abs(t[k].p[]-q[]));
int dl=t[k].l?calmx(t[k].l):-INF,dr=t[k].r?calmx(t[k].r):-INF;
if(dl>dr){if(dl>D)qmx(t[k].l);if(dr>D)qmx(t[k].r);}
else{if(dr>D)qmx(t[k].r);if(dl>D)qmx(t[k].l);}
}
inline int calmn(int k)
{
return max(t[k].mn[]-q[],)+max(q[]-t[k].mx[],)+
max(t[k].mn[]-q[],)+max(q[]-t[k].mx[],);
}
void qmn(int k)
{
int x=abs(t[k].p[]-q[])+abs(t[k].p[]-q[]);if(x)D=min(D,x);
int dl=t[k].l?calmn(t[k].l):INF,dr=t[k].r?calmn(t[k].r):INF;
if(dl<dr){if(dl<D)qmn(t[k].l);if(dr<D)qmn(t[k].r);}
else{if(dr<D)qmn(t[k].r);if(dl<D)qmn(t[k].l);}
}
int main()
{
int n=read(),i,x,ans=INF;
for(i=;i<=n;++i)t[i].p[]=read(),t[i].p[]=read();
rt=build(,n);
for(i=;i<=n;++i)
{
q[]=t[i].p[];q[]=t[i].p[];
D=-INF;qmx(rt);x=D;
D=INF;qmn(rt);
ans=min(ans,x-D);
}
printf("%d",ans);
}
2. [BZOJ]2648: SJY摆棋子
题目大意:一开始有n个黑棋,m次操作,每次多摆一个黑棋或者摆上一个白棋并询问离这个白棋最近的黑棋的距离,距离为曼哈顿距离。(n,m<=500,000)
思路:k-d tree裸题,暴力插点可过,也可以分块重构。
暴力插
#include<cstdio>
#include<algorithm>
using namespace std;
inline int read()
{
int x;char c;
while((c=getchar())<''||c>'');
for(x=c-'';(c=getchar())>=''&&c<='';)x=(x<<)+(x<<)+c-'';
return x;
}
#define MN 1000000
#define INF 0x7FFFFFFF
int rt,D,q[];
struct node
{
int p[],mn[],mx[],l,r;
friend bool operator<(const node&a,const node&b){return a.p[D]<b.p[D];}
}t[MN+];
inline void up(int k)
{
for(int l=t[k].l,r=t[k].r,i=;i<;++i)
t[k].mn[i]=t[k].mx[i]=t[k].p[i],
l?(t[k].mn[i]=min(t[k].mn[i],t[l].mn[i]),t[k].mx[i]=max(t[k].mx[i],t[l].mx[i])):,
r?(t[k].mn[i]=min(t[k].mn[i],t[r].mn[i]),t[k].mx[i]=max(t[k].mx[i],t[r].mx[i])):;
}
int build(int l,int r)
{
if(l>r)return ;
int mid=l+r>>;D^=;
nth_element(t+l,t+mid,t+r+);
t[mid].l=build(l,mid-);
t[mid].r=build(mid+,r);
return D^=,up(mid),mid;
}
void ins(int&k,int x){k?(D^=,ins(t[x]<t[k]?t[k].l:t[k].r,x),):(k=x,);up(k);}
inline int cal(int k)
{
return k?max(t[k].mn[]-q[],)+max(q[]-t[k].mx[],)+
max(t[k].mn[]-q[],)+max(q[]-t[k].mx[],):INF;
}
void query(int k)
{
D=min(D,abs(t[k].p[]-q[])+abs(t[k].p[]-q[]));
int dl=cal(t[k].l),dr=cal(t[k].r);
if(dl<dr){if(dl<D)query(t[k].l);if(dr<D)query(t[k].r);}
else{if(dr<D)query(t[k].r);if(dl<D)query(t[k].l);}
}
int main()
{
int n,m,i;
n=read();m=read();
for(i=;i<=n;++i)t[i].p[]=read(),t[i].p[]=read();
rt=build(,n);
while(m--)read()<?
(t[++n].p[]=read(),t[n].p[]=read(),D=,ins(rt,n),):
(q[]=read(),q[]=read(),D=INF,query(rt),printf("%d\n",D));
}
替罪羊重构版,貌似比暴力还慢……
#include<cstdio>
#include<algorithm>
using namespace std;
inline int read()
{
int x;char c;
while((c=getchar())<''||c>'');
for(x=c-'';(c=getchar())>=''&&c<='';)x=(x<<)+(x<<)+c-'';
return x;
}
#define MN 1000000
#define INF 0x7FFFFFFF
#define alpha 0.75
int rt,D,q[],rD,*rb,rq[MN+],qn;
struct node
{
int p[],mn[],mx[],l,r,s;
friend bool operator<(const node&a,const node&b){return a.p[D]<b.p[D];}
}t[MN+];
inline void up(int k)
{
t[k].s=t[t[k].l].s+t[t[k].r].s+;
for(int l=t[k].l,r=t[k].r,i=;i<;++i)
t[k].mn[i]=t[k].mx[i]=t[k].p[i],
l?(t[k].mn[i]=min(t[k].mn[i],t[l].mn[i]),t[k].mx[i]=max(t[k].mx[i],t[l].mx[i])):,
r?(t[k].mn[i]=min(t[k].mn[i],t[r].mn[i]),t[k].mx[i]=max(t[k].mx[i],t[r].mx[i])):;
}
void get(int k)
{
if(!k)return;
rq[++qn]=k;
get(t[k].l);get(t[k].r);
}
bool cmp(int a,int b){return t[a]<t[b];}
int build(int l,int r)
{
if(l>r)return ;
int mid=l+r>>;D^=;
nth_element(rq+l,rq+mid,rq+r+,cmp);
t[rq[mid]].l=build(l,mid-);
t[rq[mid]].r=build(mid+,r);
return D^=,up(rq[mid]),rq[mid];
}
void ins(int&k,int x)
{
D^=;k?(ins(t[x]<t[k]?t[k].l:t[k].r,x),):(k=x,);up(k);D^=;
if(t[t[x].l].s>t[x].s*alpha||t[t[x].r].s>t[x].s*alpha)rb=&k,rD=D;
}
inline int cal(int k)
{
return k?max(t[k].mn[]-q[],)+max(q[]-t[k].mx[],)+
max(t[k].mn[]-q[],)+max(q[]-t[k].mx[],):INF;
}
void query(int k)
{
D=min(D,abs(t[k].p[]-q[])+abs(t[k].p[]-q[]));
int dl=cal(t[k].l),dr=cal(t[k].r);
if(dl<dr){if(dl<D)query(t[k].l);if(dr<D)query(t[k].r);}
else{if(dr<D)query(t[k].r);if(dl<D)query(t[k].l);}
}
int main()
{
int n,m,i;
n=read();m=read();
for(i=;i<=n;++i)t[i].p[]=read(),t[i].p[]=read(),rq[i]=i;
rt=build(,n);
while(m--)read()<?
(t[++n].p[]=read(),t[n].p[]=read(),D=,rb=,ins(rt,n),rb?(qn=,get(*rb),D=rD,*rb=build(,qn),):):
(q[]=read(),q[]=read(),D=INF,query(rt),printf("%d\n",D));
}
3. [BZOJ]4066: 简单题
题目大意:一个n*n的矩阵,一开始元素均为0,每次使一个元素加上一个值或者查询一个子矩阵内元素和,强制在线,内存限制20MB。(n<=500,000,操作数<=200,000)
思路:cdq和线段树都被封死了,用k-d tree分块重构乱暴力,复杂度O(能过)。
#include<cstdio>
#include<algorithm>
using namespace std;
inline int read()
{
int x;char c;
while((c=getchar())<''||c>'');
for(x=c-'';(c=getchar())>=''&&c<='';)x=(x<<)+(x<<)+c-'';
return x;
}
#define MN 200000
#define INF 0x7FFFFFFF
int rt,D,mn[],mx[];
struct node
{
int p[],w,mn[],mx[],l,r,s;
friend bool operator<(const node&a,const node&b){return a.p[D]<b.p[D];}
}t[MN+];
inline void up(int k)
{
t[k].s=t[t[k].l].s+t[t[k].r].s+t[k].w;
for(int l=t[k].l,r=t[k].r,i=;i<;++i)
t[k].mn[i]=t[k].mx[i]=t[k].p[i],
l?(t[k].mn[i]=min(t[k].mn[i],t[l].mn[i]),t[k].mx[i]=max(t[k].mx[i],t[l].mx[i])):,
r?(t[k].mn[i]=min(t[k].mn[i],t[r].mn[i]),t[k].mx[i]=max(t[k].mx[i],t[r].mx[i])):;
}
int build(int l,int r)
{
if(l>r)return ;
int mid=l+r>>;D^=;
nth_element(t+l,t+mid,t+r+);
t[mid].l=build(l,mid-);
t[mid].r=build(mid+,r);
return D^=,up(mid),mid;
}
void ins(int&k,int x){D^=;k?(ins(t[x]<t[k]?t[k].l:t[k].r,x),):(k=x,);up(k);}
inline bool in(int k)
{
return mn[]<=t[k].mn[]&&t[k].mx[]<=mx[]&&
mn[]<=t[k].mn[]&&t[k].mx[]<=mx[];
}
inline bool pin(int k)
{
return mn[]<=t[k].p[]&&t[k].p[]<=mx[]&&
mn[]<=t[k].p[]&&t[k].p[]<=mx[];
}
inline bool out(int k)
{
return mx[]<t[k].mn[]||mn[]>t[k].mx[]||
mx[]<t[k].mn[]||mn[]>t[k].mx[];
}
int query(int k)
{
return !k||out(k)?:in(k)?t[k].s:(pin(k)?t[k].w:)+query(t[k].l)+query(t[k].r);
}
int main()
{
int n=,l=,p;read();
while((p=read())<)
if(p<)
{
t[++n].p[]=read()^l;t[n].p[]=read()^l;t[n].w=read()^l;
D=;t[rt].s%?(ins(rt,n),):rt=build(,n);
}
else
{
mn[]=read()^l;mn[]=read()^l;
mx[]=read()^l;mx[]=read()^l;
printf("%d\n",l=query(rt));
}
}
k-d tree模板练习的更多相关文章
- 通用动态树(Link-Cut Tree)模板
一个没有维护任何东西的动态树模板 忘了怎么写可以直接来粘 int ch[300010][2], fa[300010], st[300010]; bool lazy[300010]; bool nroo ...
- POJ1442-查询第K大-Treap模板题
模板题,以后要学splay,大概看一下treap就好了. #include <cstdio> #include <algorithm> #include <cstring ...
- ACM-ICPC 2018 沈阳赛区网络预赛-D:Made In Heaven(K短路+A*模板)
Made In Heaven One day in the jail, F·F invites Jolyne Kujo (JOJO in brief) to play tennis with her. ...
- 最小k度最小生成树模板
代码是抄的 题解是瞄的 可我想学习的心是真的嘤嘤嘤 然而 还是上传一份ioi大神的论文吧 链接:https://pan.baidu.com/s/1neIW9QeZEa0hXsUqJTjmeQ 密码:b ...
- poj2449(k短路&A_star模板)
题目链接:http://poj.org/problem?id=2449 题意:给出一个有向图,求s到t的第k短路: 思路:k短路模板题,可以用A_star模板过: 单源点最短路径+高级搜索A*;A*算 ...
- 洛谷P3690 Link Cut Tree (模板)
Link Cut Tree 刚开始写了个指针版..调了一天然后放弃了.. 最后还是学了黄学长的板子!! #include <bits/stdc++.h> #define INF 0x3f3 ...
- BZOJ 2648 / 2716 K-D Tree 模板题
#include <cstdio> #include <cmath> #include <cstring> #include <algorithm> # ...
- Codeforces 600E - Lomsat gelral 「$Dsu \ on \ tree$模板」
With $Dsu \ on \ tree$ we can answer queries of this type: How many vertices in the subtree of verte ...
- 字符串匹配--(K)MP模板
大白书型模板,并没有写成函数形式: 这个是下标从0开始的: 此外,对于一个长度为 m 的串自匹配,在此模板中 m-p[m] 就是这个串的最小循环节长度(最后一个循环可以不完整) 另一个关于自匹配后的失 ...
随机推荐
- bug终结者 团队作业第二周
bug终结者 团队作业第二周 我们小组选取游戏"开心消消乐",回答问题: 1. 此类软件是什么时候开始出现的, 这些软件是怎么说服你(陌生人)成为他们的用户的? 他们的目标都是盈利 ...
- alpha-咸鱼冲刺day2-紫仪
总汇链接 一,合照 emmmmm.自然是没有的. 二,项目燃尽图 三,项目进展 今天并没有什么进展,弄了好久好像也只研究出怎么把JS的功能块插入进去.html的信息提交这些还不知道要怎么弄. 四,问题 ...
- Android网络传输中必用的两个加密算法:MD5 和 RSA 及Base64加密总结
(1)commons-codec包简介 包含一些通用的编码解码算法.包括一些语音编码器,Hex,Base64.MD5 一.md5.base64.commons-codec包 commons-codec ...
- vue2.X简单翻页/分页
由于业务需要 公司把后台所有数据一次性给前端,数据过多,所以前端需要做一些分页的处理,比较简单的翻页. html代码 <table class="three_td"> ...
- 201421123042 《Java程序设计》第4周学习总结
1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 继承中的关键词:Soper,object,override,project, 1.2 尝试使用思维导图将这些关键词组织起来.注: ...
- c++ 中lambda
C++ 11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作. 1.Lambda表达式完整的声明格式如下: [capture list] (params list) mutable ...
- 数据结构与算法 —— 链表linked list(02)
我们继续来看链表的第二道题,来自于leetcode: 两数相加 给定两个非空链表来代表两个非负整数,位数按照逆序方式存储,它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了 ...
- UML开发工具Rose ralation的破解安装,
UML开发工具Rose ralation的在windows764破解安装, 安装下载还可以参考:http://www.cnblogs.com/leaven/p/3718361.html 跟大家分享怎么 ...
- Clover3(可以让Windows Explorer像浏览器一样有标签页)
这不是广告!!! 下载地址:http://cn.ejie.me/ 效果图:
- Web Api 利用 cors 实现跨域
一.安装 cors 二.修改 Web.config <appSettings> <add key="cors:allowedMethods" value=&quo ...