BZOJ2716:[Violet 3]天使玩偶——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=2716
样例输入
2 3
1 1
2 3
2 1 2
1 3 3
2 4 2
样例输出
1
2
————————————————————————————————
整整一个上午的时间,终于DEBUG出来了,原来是因为我数组开小了……
首先我们很容易想到一个三元组(t,x,y),其中t为操作时间。
默认最开始给定的一些点的操作为插入,且时间优先级均高于其他的点。
那么显然就是三维偏序,CDQ可以上了。
给t排个序,边归并x边树状数组记录y,然后查即可……
但是我们怎么求dis啊?
我们有种玄学的方法叫做分情况讨论。
分成四种情况:
对于(x,y)(x1,y1)的dis:
x+y-(x1+y1) (x>x1,y>y1)
x-y-(x1-y1) (x>x1,y<y1)
-x+y-(y1-x1) (x<x1,y>y1)
-x-y-(-x1-y1) (x<x1,y<y1)
其中括号内的东西就是我们要用树状数组来维护的东西,显然当括号内的东西最大的时候我们的距离有最小值。
那么就变成了维护区间最大值的问题了,显然树状数组是能够胜任这项工作的。
具体的实现方法看我代码吧……不好描述。
#include<cstdio>
#include<queue>
#include<cctype>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
const int M=;
const int N=;
const int INF=*N;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct rem{
int t;
int x;
int y;
int pos;
}q[*M],tmp[*M];
int m,n,cnt=,ans[M],tree[N],maxy=-;
bool cmp(rem a,rem b){
return (a.t<b.t||(a.t==b.t&&a.x<b.x)||(a.t==b.t&&a.x==b.x&&a.y<b.y)||(a.t==b.t&&a.x==b.x&&a.y==b.y&&a.pos<b.pos));
}
inline int lowbit(int t){return t&(-t);}
void add(int x,int y){
for(int i=x;i<=maxy;i+=lowbit(i))tree[i]=max(tree[i],y);
return;
}
int query(int x){
int res=-INF;
for(int i=x;i>;i-=lowbit(i))res=max(res,tree[i]);
return res;
}
void cdq(int l,int r){
if(l>=r)return;
int mid=(l+r)>>;
cdq(l,mid);cdq(mid+,r);
for(int i=l,j=l,p=mid+;i<=r;i++){
if(j<=mid&&(p>r||q[j].x<=q[p].x))tmp[i]=q[j++];
else tmp[i]=q[p++];
}
///////////
for(int i=l;i<=r;i++){
q[i]=tmp[i];
if(q[i].t<=mid&&!q[i].pos)add(q[i].y,q[i].x+q[i].y);
if(q[i].t>mid&&q[i].pos)ans[q[i].pos]=min(ans[q[i].pos],q[i].x+q[i].y-query(q[i].y));
}
for(int i=l;i<=r;i++){
if(q[i].t<=mid&&!q[i].pos){
for(int j=q[i].y;j<=maxy;j+=lowbit(j))tree[j]=-INF;
}
}
///////////
for(int i=l;i<=r;i++){
if(q[i].t<=mid&&!q[i].pos)add(maxy-q[i].y,q[i].x-q[i].y);
if(q[i].t>mid&&q[i].pos)ans[q[i].pos]=min(ans[q[i].pos],q[i].x-q[i].y-query(maxy-q[i].y));
}
for(int i=l;i<=r;i++){
if(q[i].t<=mid&&!q[i].pos){
for(int j=maxy-q[i].y;j<=maxy;j+=lowbit(j))tree[j]=-INF;
}
}
///////////
for(int i=r;i>=l;i--){
if(q[i].t<=mid&&!q[i].pos)add(q[i].y,q[i].y-q[i].x);
if(q[i].t>mid&&q[i].pos)ans[q[i].pos]=min(ans[q[i].pos],-q[i].x+q[i].y-query(q[i].y));
}
for(int i=l;i<=r;i++){
if(q[i].t<=mid&&!q[i].pos){
for(int j=q[i].y;j<=maxy;j+=lowbit(j))tree[j]=-INF;
}
}
///////////
for(int i=r;i>=l;i--){
if(q[i].t<=mid&&!q[i].pos)add(maxy-q[i].y,-q[i].x-q[i].y);
if(q[i].t>mid&&q[i].pos)ans[q[i].pos]=min(ans[q[i].pos],-q[i].x-q[i].y-query(maxy-q[i].y));
}
for(int i=l;i<=r;i++){
if(q[i].t<=mid&&!q[i].pos){
for(int j=maxy-q[i].y;j<=maxy;j+=lowbit(j))tree[j]=-INF;
}
}
///////////
return;
}
void clear(){
maxy++;
for(int i=;i<=cnt;i++)ans[i]=INF;
for(int i=;i<=maxy;i++)tree[i]=-INF;
return;
}
int main(){
n=read();
m=read();
for(int i=;i<=n;i++){
q[i].x=read()+;
q[i].y=read()+;
q[i].t=i;
maxy=max(maxy,q[i].y);
}
for(int i=n+;i<=m+n;i++){
int w=read();
if(w==){
q[i].x=read()+;
q[i].y=read()+;
q[i].t=i;
maxy=max(maxy,q[i].y);
}else{
q[i].x=read()+;
q[i].y=read()+;
q[i].t=i;
q[i].pos=++cnt;
maxy=max(maxy,q[i].y);
}
}
sort(q+,q+m+n+,cmp);
clear();
cdq(,m+n);
for(int i=;i<=cnt;i++)printf("%d\n",ans[i]);
return ;
}
BZOJ2716:[Violet 3]天使玩偶——题解的更多相关文章
- bzoj2648SJY摆棋子&&bzoj2716[Violet 3]天使玩偶*
bzoj2648SJY摆棋子 bzoj2716[Violet 3]天使玩偶 题意: 棋盘上有n个棋子,现在有m个操作,一种是加棋子,一种是查询离某个点最近的棋子.n,m≤500000. 题解: 先将已 ...
- [BZOJ2716] [Violet 3]天使玩偶(CDQ分治)
[BZOJ2716] [Violet 3]天使玩偶(CDQ分治) 题面 Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里, ...
- 【kd-tree】bzoj2716 [Violet 3]天使玩偶
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define ...
- BZOJ2716 [Violet 3]天使玩偶 【CDQ分治】
题目 输入格式 输出格式 输入样例 //样例太长就不贴了.... 输出样例 //见原题 提示 题解 我们将曼哈顿距离式子中的绝对值去掉,每次只考虑x,y比当前点小的更新答案. 为了使所有点都对答案进行 ...
- bzoj2716: [Violet 3]天使玩偶
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
- BZOJ2716: [Violet 3]天使玩偶(KD-Tree)
Description Input Output Sample Input 100 100 81 23 27 16 52 58 44 24 25 95 34 2 96 25 8 14 97 50 97 ...
- BZOJ2648: SJY摆棋子&&2716: [Violet 3]天使玩偶
BZOJ2648: SJY摆棋子 BZOJ2716: [Violet 3]天使玩偶 BZOJ氪金无极限... 其实这两道是同一题. 附上2648的题面: Description 这天,SJY显得无聊. ...
- 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分治 + 树状数组 )
先cdq分治, 然后要处理点对答案的贡献, 可以以询问点为中心分成4个区域, 然后去掉绝对值(4种情况讨论), 用BIT维护就行了. --------------------------------- ...
随机推荐
- 软考之信息安全工程师(包含2016-2018历年真题详解+官方指定教程+VIP视频教程)
软考-中级信息安全工程师2016-2018历年考试真题以及详细答案,同时含有信息安全工程师官方指定清华版教程.信息安全工程师高清视频教程.持续更新后续年份的资料.请点赞!!请点赞!!!绝对全部货真价实 ...
- Python接口测试实战4(上) - 接口测试框架实战
如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...
- 第一篇:一天学会MongoDB数据库之Python操作
本文仅仅学习使用,转自:https://www.cnblogs.com/suoning/p/6759367.html#3682005 里面新增了如果用用Python代码进行增删改查 什么是MongoD ...
- Spring Cloud(三):服务提供与调用 Eureka【Finchley 版】
Spring Cloud(三):服务提供与调用 Eureka[Finchley 版] 发表于 2018-04-15 | 更新于 2018-05-07 | 上一篇文章我们介绍了 Eureka 服务 ...
- Redis5.0:现公测全免费,点击就送,注册账号,即开即用
华为云分布式缓存服务Redis,是华为云服务的一款核心产品. 分布式缓存Redis是一款内存数据库服务,基于双机热备的高可用架构,提供单机.主从.集群等丰富类型的缓存类型. 现推出最新版本Redis5 ...
- VPS挂机赚美刀详细介绍–Alexamaster操作流程
跟 vps 主机打交道时间长了,手里也渐渐积累了些闲置的 vps.让它们这么闲着吧,感觉有些浪费资源:用起来吧,暂时又没有好的项目.一直听说通过 vps挂机可以赚回主机成本,甚至可以盈利.正好这两天有 ...
- python基础知识-01-编码输入输出变量
python其他知识目录 名词解释: 编辑器 ide 程序员 操作系统 ASCAII码 unicode utf-8 浅谈CPU.内存.硬盘之间的关系 操作系统及Python解释器工作原理讲解 关于编译 ...
- 启动tomcat时 一闪而过解决方法(2)
下面我先跟大家确认一下问题出现的前提条件(本机版本java:1.6.20,tomcat:6.0.32) 1)在eclipse里面启动tomcat时都是正常的. 2)在系统中配置了各种环境变量如下: J ...
- Python20-Day02
1.数据 数据为什么要分不同的类型 数据是用来表示状态的,不同的状态就应该用不同类型的数据表示: 数据类型 数字(整形,长整形,浮点型,复数),字符串,列表,元组,字典,集合 2.字符串 1.按索引取 ...
- redis利用key计时与计数
计时 Setex 命令为指定的 key 设置值及其过期时间.如果 key 已经存在, SETEX 命令将会替换旧的值 基本命令: redis 127.0.0.1:6379> SETEX KEY_ ...