【bzoj 2716】[Violet 3]天使玩偶 (CDQ+树状数组)
题目描述
Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下。而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里,所以她决定仅凭一点模糊的记忆来寻找它。
我们把 Ayu 生活的小镇看作一个二维平面坐标系,而 Ayu 会不定时地记起可能在某个点 (xmy) 埋下了天使玩偶;或者 Ayu 会询问你,假如她在 (x,y) ,那么她离近的天使玩偶可能埋下的地方有多远。
因为 Ayu 只会沿着平行坐标轴的方向来行动,所以在这个问题里我们定义两个点之间的距离为dist(A,B)=|Ax-Bx|+|Ay-By|。其中 Ax 表示点 A的横坐标,其余类似。
输入输出格式
输入格式:
第一行包含两个整数n和m ,在刚开始时,Ayu 已经知道有n个点可能埋着天使玩偶, 接下来 Ayu 要进行m 次操作
接下来n行,每行两个非负整数 (xi,yi),表示初始n个点的坐标。
再接下来m 行,每行三个非负整数 t,xi,yi。
如果t=1 ,则表示 Ayu 又回忆起了一个可能埋着玩偶的点 (xi,yi) 。
如果t=2 ,则表示 Ayu 询问如果她在点 (xi,yi) ,那么在已经回忆出来的点里,离她近的那个点有多远
输出格式:
对于每个t=2 的询问,在单独的一行内输出该询问的结果。
输入输出样例
说明
n,m<=300 000
xi,yi<=1 000 000
题解
先膜一发大佬
据说这题正解KD-tree,然而我只会CDQ……还想了半天啥都没想出来……
先假设,所有回忆出来的点都在查询点的左下方,那么距离如下(A为查询点,B为某一个回忆出来的点)
$$Dist(A,B)=|x_A-x_B|+|y_A-y_B|=(x_A+y_A)-(x_B+y_B)$$
因为$x_A+y_A$对同一个查询点来说是一个定值,所以只要找到$x_B+y_B$的最大值,就可以找到$Dist(A,B)$的最小值
于是问题就转化为:对于一个询问$(x,y)$,查找$x_i<=x,y_i<=y$且$i$的时间戳小于当前询问的最大$x_i+y_i$,很明显,这就是一个三维偏序问题,可以用CDQ求解
然而问题是不能保证所有点都在查询点的下方,所以我们要将其他四个方位的点的坐标变换一下。简单来说就是旋转整张图,然后在四个答案里取最小的就好了
所以做四遍CDQ(当初刚看到这句话差点没吓到……)
然后有几个向大佬学习的优化
1.每次CDQ前,把肯定不在左下方的点去掉
2.每一次重新建图很麻烦,直接保留一个原图然后转一下就好了
感觉我对CDQ理解还是太浅了……
//minamoto
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,:;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,:;}
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(int x){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=1e6+,inf=0x3f3f3f3f;
int n,m,lx,ly,rx,ry,c[N],ans[N];
inline void clear(int x){
for(int i=x;i<=ly;i+=i&-i)
if(c[i]) c[i]=;else break;
}
inline void add(int x,int val){
for(int i=x;i<=ly;i+=i&-i)
cmax(c[i],val);
}
inline int query(int x){
int res=;
for(int i=x;i;i-=i&-i)
cmax(res,c[i]);
return res;
}
struct node{
int x,y,t;bool f;
node(){}
node(const int &x,const int &y,const int &t,const int &f):
x(x),y(y),t(t),f(f){}
inline bool operator <(const node &b)const
{return x<b.x||(x==b.x&&y<b.y);}
}a[N],p[N],q[N];
void CDQ(int l,int r){
if(l==r) return;
int mid=(l+r)>>;
CDQ(l,mid),CDQ(mid+,r);
int j=l;
for(int i=mid+;i<=r;++i)
if(!p[i].f){
while(j<=mid&&p[j].x<=p[i].x){if(p[j].f) add(p[j].y,p[j].x+p[j].y);++j;}
int tmp=query(p[i].y);
if(tmp) tmp=p[i].x+p[i].y-tmp,cmin(ans[p[i].t],tmp);
}
for(int i=l;i<j;++i)
if(p[i].f) clear(p[i].y);
merge(p+l,p+mid+,p+mid+,p+r+,q+l);
memcpy(p+l,q+l,sizeof(node)*(r-l+));
}
void check(){
rx=ry=m=;
for(int i=;i<=n;++i)
if(!p[i].f) cmax(rx,p[i].x),cmax(ry,p[i].y);
for(int i=;i<=n;++i)
if(p[i].x<=rx&&p[i].y<=ry) q[++m]=p[i];
memcpy(p+,q+,sizeof(node)*m);
}
int main(){
//freopen("testdata.in","r",stdin);
n=read(),m=read();
for(int i=;i<=n;++i){
int x=read()+,y=read()+;
p[i]=(node){x,y,i,true};
cmax(lx,x),cmax(ly,y);
}
while(m--){
int k=read(),x=read()+,y=read()+;
++n,p[n]=node(x,y,n,k&);
cmax(lx,x),cmax(ly,y);
}
memcpy(a+,p+,sizeof(node)*n);
memset(ans,inf,sizeof(ans));
check(),CDQ(,m);
for(int i=;i<=n;++i)
p[i]=a[i],p[i].x=lx-p[i].x+;
check(),CDQ(,m);
for(int i=;i<=n;++i)
p[i]=a[i],p[i].y=ly-p[i].y+;
check(),CDQ(,m);
for(int i=;i<=n;++i)
p[i]=a[i],p[i].y=ly-p[i].y+,p[i].x=lx-p[i].x+;
check(),CDQ(,m);
for(int i=;i<=n;++i)
if(!a[i].f) print(ans[i]);
Ot();
return ;
}
【bzoj 2716】[Violet 3]天使玩偶 (CDQ+树状数组)的更多相关文章
- BZOJ 2716: [Violet 3]天使玩偶( CDQ分治 + 树状数组 )
先cdq分治, 然后要处理点对答案的贡献, 可以以询问点为中心分成4个区域, 然后去掉绝对值(4种情况讨论), 用BIT维护就行了. --------------------------------- ...
- BZOJ 2716 [Violet 3]天使玩偶 (CDQ分治、树状数组)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2716 怎么KD树跑得都那么快啊..我写的CDQ分治被暴虐 做四遍CDQ分治,每次求一个 ...
- BZOJ 2716 Violet 3 天使玩偶 CDQ分治
题目大意:初始给定平面上的一个点集.提供两种操作: 1.将一个点增加点集 2.查询距离一个点最小的曼哈顿距离 K-D树是啥...不会写... 我仅仅会CDQ分治 对于一个询问,查询的点与这个点的位置关 ...
- BZOJ 2716: [Violet 3]天使玩偶
2716: [Violet 3]天使玩偶 Time Limit: 80 Sec Memory Limit: 128 MBSubmit: 1473 Solved: 621[Submit][Statu ...
- bzoj 2716 [Violet 3]天使玩偶 【CDQ分治】
KD-tree可做,但是我不会暂时不考虑 大意:在二维平面内,给定n个点,m个操作.操作A:加入一个点:操作B:询问一个点与平面上加入的点的最近距离 不封装会T不封装会T不封装会T不封装会T不封装会 ...
- BZOJ 1176/2683 Mokia (三维偏序CDQ+树状数组)
题目大意: 洛谷传送门 三维偏序裸题.. 每次操作都看成一个三元组$<x,y,t>$,表示$x,y$坐标和操作时间$t $ 询问操作拆成$4$个容斥 接下来就是$CDQ$了,外层按t排序, ...
- bzoj 2716 [Violet 3]天使玩偶——KDtree
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2716 第三道KDtree!仍旧是模板.还有CDQ分治做法,见下面. 数组迷之开大?(开6e5 ...
- BZOJ 2716 [Violet 3]天使玩偶 ——KD-Tree
[题目分析] KD-Tree的例题.同BZOJ2648. [代码] #include <cstdio> #include <cstring> #include <cstd ...
- bzoj 2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 --kdtree
2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 Time Limit: 20 Sec Memory Limit: 128 MB Description 这天,S ...
- [BZOJ2716] [Violet 3]天使玩偶(CDQ分治)
[BZOJ2716] [Violet 3]天使玩偶(CDQ分治) 题面 Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里, ...
随机推荐
- windows到ubuntu
按照xmarks同步浏览器书签. mvn, copy setting.xml 最好不要用apt-get install maven, 占用/的磁盘空间 mvn -U package -P"d ...
- NotePad++替换行前、行后空格,替换空行
用 Notepad++ 打开,把每一个将要放在表中单元格的内容放一行(注: ^ 代表行首 $ 代表行尾) 去除行尾空格和空白行:按CTRL+H 选择正则表达式– 查找目标:\s+$ 替换为空 去除行首 ...
- 《C语言基础日常笔记》
1. 类型转换-----------------20130902 a, 浮点数(包括单精度与双精度)赋值给整型变量时,舍弃浮点数的小数部分,直接将其整数部分存放在整型变量里. b, 整型变量赋值给浮点 ...
- Linux内存地址映射
引言 看过原博主的一些文章,写得很好,虽然博主不提倡这种拿来主义,但我还是忍不住一时手痒.呵呵本文是针对32位x86 CPU中Linux内核地址映射过程的详细介绍和示例.其中由浅入深,介绍了相关寄存器 ...
- Information Retrieval II
[Information Retrieval II] 搜索引擎分类: 1.目录式搜索引擎. 2.全文搜索引擎. 3.元搜索引擎(Meta-Search Engine). 搜索引擎的4个阶段:下载(cr ...
- Matlab界面清洗
保持干净清爽的编程界面可以给人以简洁明朗的享受,Matlab可以对涉及到的4个界面进行清洗: ① Clear Figure ; ② Clear Command window; ③ Clear Wor ...
- java webservice maven spring Class Not Found Exception解决
project clean——>maven clean——>update maven ——>server clean——>build project ——>maven i ...
- 配置yum源方法,以及失效时的处理
正常方法如下: step1: 备份原CentOS-Base.repo 文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-B ...
- Java 设计模式系列(八)装饰者模式
Java 设计模式系列(八)装饰者模式 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案.Decorator 或 Wrapper 一.装饰模 ...
- Linux之chmod使用
Linux文件分三种身份和四中权限. u:文件的拥有者 g:文件所属的群组 o:其他用户 对于每个身份,又有四种权限,分别为: r:读取文件的权限(read) w:写入文件的权限(write) x:执 ...