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. 团队作业7——第二次项目冲刺(Beta版本12.05-12.07)

    1.当天站立式会议照片 本次会议内容:1:每个人汇报自己完成的工作.2:组长分配各自要完成的任务. 2.每个人的工作 黄进勇:项目整合,后台代码. 李勇:前台界面优化. 何忠鹏:数据库模块. 郑希彬: ...

  2. python day1 基本语法作业

    一.过7 start =1 while start<=10: if start !=7: print(start) start +=1 二.100以内的和 sum = 0 start = 1 w ...

  3. 【iOS】swift 排序Sort函数用法(包含NSDictionary排序)

    用了几分钟做的简单翻译 一个例子 直接贴代码,不过多解释 //这是我们的model class imageFile { var fileName = String() var fileID = Int ...

  4. Digilent Xilinx USB Jtag cable

    Digilent Xilinx USB Jtag cable 安装环境 操作系统:fedora 20 64bit 源链接:https://wiki.gentoo.org/wiki/Xilinx_USB ...

  5. 关于安装win7系统时出现0x0000007b电脑蓝屏代码的问题

    问题解析: 0X0000007B 这个错误网上都说是sata硬盘的什么引导模式的原因引起. 在网上查找了很久,大概引起错误的原因就是:sata和ide两种模式不同,前者可以装win7系统,后者是xp系 ...

  6. 洛谷 U10783 名字被和谐了

    https://www.luogu.org/problem/show?pid=U10783 题目背景 众所周知,我们称g是a的约数,当且仅当g是正数且a mod g = 0. 众所周知,若g既是a的约 ...

  7. [Android FrameWork 6.0源码学习] View的重绘过程之WindowManager的addView方法

    博客首页:http://www.cnblogs.com/kezhuang/p/关于Activity的contentView的构建过程,我在我的博客中已经分析过了,不了解的可以去看一下<[Andr ...

  8. 返回到前台的String出现乱码问题

    使用springmvc给前天返回String类型的数据出现乱码问题可以在配置环境Spring-mvc.xml中添加如下代码 <mvc:annotation-driven> <mvc: ...

  9. Java Jar包压缩、解压使用指南

    什么是jar包 JAR(Java Archive)是Java的归档文件,它是一种与平台无关的文件格式,它允许将许多文件组合成一个压缩文件. 如何打/解包 使用jdk/bin/jar.exe工具,配置完 ...

  10. Spring知识点回顾(06)Profile 和 条件注解 @Conditional

    1.设定环境中的active profiles 如:DispatcherServerlet的init-param spring.profiles.active=production spring.pr ...