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] 就是这个串的最小循环节长度(最后一个循环可以不完整) 另一个关于自匹配后的失 ...
随机推荐
- 设计模式NO.3
设计模式NO.3 本次博客内容为第三次设计模式的练习.根据老师的要求完成下列题目: 题目1 某商品管理系统的商品名称存储在一个字符串数组中,现需要自定义一个双向迭代器(MyIterator)实现对该商 ...
- jQuery函数学习
函数:after(content) 功能:在每个匹配的元素后面添加html内容 返回:jQuery对象 参数:content (<Content>): Content to insert ...
- 机器学习中 K近邻法(knn)与k-means的区别
简介 K近邻法(knn)是一种基本的分类与回归方法.k-means是一种简单而有效的聚类方法.虽然两者用途不同.解决的问题不同,但是在算法上有很多相似性,于是将二者放在一起,这样能够更好地对比二者的异 ...
- LeetCode & Q189-Rotate Array-Easy
Array Description: Rotate an array of n elements to the right by k steps. For example, with n = 7 an ...
- CentOS 7 使用yum安装出现错误
CentOS 7 使用yum安装软件出现错误: Loaded plugins: fastestmirror 此错误信息可能是因为DNS配置错误,可以通过更改配置文件来解决: 1. 使用vi打开DNS的 ...
- 新概念英语(1-129)Seventy miles an hour
Lesson 129 Seventy miles an hour 时速70英里 Listen to the tape then answer this question. What does Ann ...
- redis入门(03)redis的配置
一.配置文件 Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf.你可以通过 CONFIG 命令查看或设置配置项. 二.查看修改 1.查看配置 1.1.vi redis ...
- 浅显易懂的谈一谈python中的装饰器!!
hello大家好~~我是稀里糊涂林老冷,一天天稀里糊涂的. 前一段时间学习了装饰器,觉着这东西好高大上哇靠!!哈哈,一定要总结一下,方便以后自己查阅,也希望帮助其他伙伴们共同进步! 装饰器: 大家可以 ...
- js、jQuery 获取文档、窗口、元素的各种值
基于两年开发经验,总结了 javascript.jQuery 获取窗口.文档.元素的各种值 javascript: 文档:是整个document所有的内容 浏览器当前窗口文档body的宽度: docu ...
- mysql 存储过程 实现数据同步
数据库 表 发生变化,需要把2.0的表数据 同步到3.0库中去: -- 同步数据存储过程执行 -- 更新留言旧表数据到新表数据中 /*DEFINER:Vector*/ drop procedure i ...