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模板练习的更多相关文章

  1. 通用动态树(Link-Cut Tree)模板

    一个没有维护任何东西的动态树模板 忘了怎么写可以直接来粘 int ch[300010][2], fa[300010], st[300010]; bool lazy[300010]; bool nroo ...

  2. POJ1442-查询第K大-Treap模板题

    模板题,以后要学splay,大概看一下treap就好了. #include <cstdio> #include <algorithm> #include <cstring ...

  3. 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. ...

  4. 最小k度最小生成树模板

    代码是抄的 题解是瞄的 可我想学习的心是真的嘤嘤嘤 然而 还是上传一份ioi大神的论文吧 链接:https://pan.baidu.com/s/1neIW9QeZEa0hXsUqJTjmeQ 密码:b ...

  5. poj2449(k短路&A_star模板)

    题目链接:http://poj.org/problem?id=2449 题意:给出一个有向图,求s到t的第k短路: 思路:k短路模板题,可以用A_star模板过: 单源点最短路径+高级搜索A*;A*算 ...

  6. 洛谷P3690 Link Cut Tree (模板)

    Link Cut Tree 刚开始写了个指针版..调了一天然后放弃了.. 最后还是学了黄学长的板子!! #include <bits/stdc++.h> #define INF 0x3f3 ...

  7. BZOJ 2648 / 2716 K-D Tree 模板题

    #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> # ...

  8. 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 ...

  9. 字符串匹配--(K)MP模板

    大白书型模板,并没有写成函数形式: 这个是下标从0开始的: 此外,对于一个长度为 m 的串自匹配,在此模板中 m-p[m] 就是这个串的最小循环节长度(最后一个循环可以不完整) 另一个关于自匹配后的失 ...

随机推荐

  1. C语言——第十四、十五周作业

    题目 题目一:交换最小值和最大值 1.实验代码 #include<stdio.h> int main() { ; int i , n; int a[N]; int x , y; scanf ...

  2. fflush(stdin)与fflush(stdout)

    1.fflush(stdin): 作用:清理标准输入流,把多余的未被保存的数据丢掉.. 如: int main() { int num; char str[10]; cin>>num; c ...

  3. 使用XIB实现嵌套自定义视图

    在进行iOS开发的过程中,对于一些复杂的界面,我们可以通过Interface Builder这个Xcode集成的可视化界面编辑工具在完成,这回节省大部分时间以及代码量.它的使用方法这里不做介绍了,这次 ...

  4. javascript参数传递中处理+号

    在传值过程中,如果+号也是值的一部分,那就需要对+号进行处理.否则+号会被过滤掉. 处理方式:只需要把js中传过去的+号替换成base64 编码 %2B encodeURI(str).replace( ...

  5. 构建自己的PHP框架--构建模版引擎(3)

    之前我们实现了最简单的echo命令的模版替换,就是将{{ $name }}这样一段内容替换成<?php echo $name ?>. 现在我们来说下其他的命令,先来回顾下之前的定义 输出变 ...

  6. 第一章 创建WEB项目

    第一章   创建WEB项目 一.Eclipse创建WEB项目 方法/步骤1 首先,你要先打开Eclipse软件,打开后在工具栏依次点击[File]>>>[New]>>&g ...

  7. 用‘+=’拼接字符串,打印时总会出现一个undefined

    var str; for(var i = 0; i < 5; i++){ str += String(i); } console.log(str); 他喵的,打印的结果竟然是"unde ...

  8. Django admin 中抛出 'WSGIRequest' object has no attribute 'user'的错误

    这是Django版本的问题,1.9之前,中间件的key为MIDDLEWARE_CLASSES, 1.9之后,为MIDDLEWARE.所以在开发环境和其他环境的版本不一致时,要特别小心,会有坑. 将se ...

  9. Celery 分布式任务队列快速入门

    Celery 分布式任务队列快速入门 本节内容 Celery介绍和基本使用 在项目中如何使用celery 启用多个workers Celery 定时任务 与django结合 通过django配置cel ...

  10. python 类和对象

    类和对象 类 1.类的组成    数据和函数,二者是类的属性 2.两个作用: 实例化 属性引用  属性引用:类名.属性(增删改查)   实例化: 类名加括号就是实例化,会自动出发__init__的运行 ...