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] 就是这个串的最小循环节长度(最后一个循环可以不完整) 另一个关于自匹配后的失 ...
随机推荐
- 20162323周楠《Java程序设计与数据结构》第六周总结
学号 2016-2017-2 <程序设计与数据结构>第六周学习总结 教材学习内容总结 继承:从已有类派生一个新类,是面向对象程序设计的一个特点 在Java中只支持单继承,不支持多继承 继承 ...
- C语言-第一次作业
题目6-1 计算两数的和与差 1.设计思路 (1)主要描述题目算法 第一步:看主函数知道程序输入浮点型变量a,b,通过函数计算输出和与差. 第二步:函数部分将a赋值op1,b赋值op2,&su ...
- 下载文件downloadFile
public static void downLoadFile(InputStream inStream, String fileName) { if (StringUtils.isBlank(fil ...
- 项目Beta冲刺Day4
项目进展 李明皇 今天解决的进度 因服务器端未完成登录态维护,故无法进行前后端联动. 明天安排 前后端联动调试 林翔 今天解决的进度 因上课和实验室事务未完成登录态维护 明天安排 完成登录态维护 孙敏 ...
- C实现单链表
typedef int DataType; typedef struct ListNode { DataType data; struct ListNode* next; }ListNode; //初 ...
- [Redis源码阅读]redis持久化
作为web开发的一员,相信大家的面试经历里少不了会遇到这个问题:redis是怎么做持久化的? 不急着给出答案,先停下来思考一下,然后再看看下面的介绍.希望看了这边文章后,你能够回答这个问题. 为什么需 ...
- ThreadLocal源码分析:(一)set(T value)方法
在ThreadLocal的get(),set()的时候都会清除线程ThreadLocalMap里所有key为null的value. 而ThreadLocal的remove()方法会先将Entry中对k ...
- spring MVC框架入门(外加SSM整合)
spring MVC框架 一.什么是sping MVC Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 W ...
- 详解Windows Server 2008 R2下安装Oracle 11g
本篇文章转载 http://www.it165.net/database/html/201212/3385.html 一.安装前的准备工作: 1. 修改计算机名: 服务器的计算机名称对于登录到Orac ...
- oracle11g导出表时会发现少表,空表导不出解决方案
oracle11g导出表时会发现少表,空表导不出解决方案. 一:背景引入 oracle11g用exp命令导出数据库表时,有时会发现只导出了一部分表时而且不会报错,原因是有空表没有进行导出,之前一直 ...