洛谷P4169 天使玩偶 CDQ分治
还是照着CDQ的思路来。
但是有一些改动:
- 要求4个方向的,但是可爱的CDQ分治只能求在自己一个角落方向上的。怎么办?旋转!做4次就好了。
- 统计的不是和,而是——max!理由如下:
设当前点是(x,y),目标点是(x',y'),那么所求的|x-x'|+|y-y'|首先用旋转大法化为x-x'+y-y',然后我们发现这个东西其实就是x+y-x'-y'=(x+y)-(x'+y'),而x+y我们是已知的。所以我们求一下max(x'+y')即可。具体实现是对树状数组魔改。
然后交上去发现狂T不止...
疯狂优化!首先把树状数组的max从作死的M改成了所有坐标中最大的mm,发现不行,跑去看题解。
发现不能每次sort,而且还要删点。
然后学习了一波操作之后,成功的到达了91分...还是有3个点死活过不了。把题解拿下来一交,发现居然也T了一个点,哈哈哈。
听从雨菲的建议,果断开O2,A了。
看代码理解删点优化和魔改树状数组。
// luogu-judger-enable-o2
#include <cstdio>
#include <algorithm>
using namespace std;
const int M = ,N = ,INF=0x3f3f3f3f;
inline int read()
{
int ans=;char ch=getchar();
while(ch<''||ch>'') ch=getchar();
while(ch>=''&&ch<='') ans=(ans<<)+(ans<<)+ch-'',ch=getchar();
return ans;
}
inline int lowbit(int x){return x&(-x);}
int ta[M+],n,mm,ans[N];int p,rx,ry;
inline void add(int x,int a)
{
if(x<=) return;
for(int i=x;i<=ry;i+=lowbit(i)) ta[i]=max(ta[i],a);
return;
}
inline int getsum(int x)
{
if(x<=)return ;int ans=-INF;
for(int i=x;i>;i-=lowbit(i)) ans=max(ans,ta[i]);
return ans;
}
inline void del(int x)
{
if(x<=) return;
for(int i=x;i<=ry;i+=lowbit(i)) ta[i]=-INF;
return;
}
struct Node
{
int x,y,k=-INF,t,type;
}node[N],temp[N],f[N];
inline bool cmp_t(Node a,Node b){return a.t<b.t;}
inline void rotate()
{
for(int i=;i<=n;i++)
{
int t=f[i].x;
f[i].x=mm-f[i].y;
f[i].y=t;
}
return;
}
void CDQ(int l,int r)
{
if(l==r) return;
int mid=(l+r)>>;
CDQ(l,mid);CDQ(mid+,r);
int i=l,j=mid+,t=;
while(i<=mid||j<=r)
{
if(j>r||(i<=mid&&node[i].x<=node[j].x))
{
if(node[i].type==) add(node[i].y,node[i].x+node[i].y);
temp[++t]=node[i++];
}
else
{
if(node[j].type>) {node[j].k=max(node[j].k,getsum(node[j].y));
ans[node[j].t]=min(ans[node[j].t],node[j].x+node[j].y-node[j].k);}
///if(node[j].type>1) node[j].k=min(node[j].k,(node[j].x+node[j].y-getsum(node[j].y)));
temp[++t]=node[j++];
}
}
t=;
for(j=l;j<i;j++) if(node[j].type==) del(node[j].y);
for(i=l;i<=r;i++) node[i]=temp[++t];
return;
} inline void Delete()
{
rx=ry=p=;
for(int i=;i<=n;i++) if(f[i].type==) rx=max(rx,f[i].x),ry=max(ry,f[i].y);
for(int i=;i<=n;i++) if(f[i].x<=rx&&f[i].y<=ry) node[++p]=f[i];
return;
}
int main()
{
fill(ta,ta+M,-INF);
int n2=read(),n3=read(),x,y,flag;
for(int i=;i<=n2;i++)
{
x=read()+;y=read()+;
f[++n].x=x;
f[n].y=y;
f[n].type=;
f[n].t=n;
mm=max(mm,x);
mm=max(mm,y);
}
for(int i=;i<=n3;i++)
{
flag=read();x=read()+;y=read()+;
f[++n].x=x;
f[n].y=y;
f[n].type=flag;
f[n].t=n;
mm=max(mm,x);
mm=max(mm,y);
}
mm++;
fill(ans+,ans+n+,INF);
for(y=;y<=;y++)
{
Delete();
ry++;
//for(int i=1;i<=p;i++) printf("%d %d %d\n",node[i].type,node[i].x,node[i].y);
CDQ(,p);
//for(int i=1;i<=n;i++)if(f[i].type==2)printf("%d ",ans[i]);
//printf("\n");
rotate();
} for(int i=;i<=n;i++)
{
if(f[i].type==) printf("%d\n",ans[i]);
} return ;
}
/**
1 3
3 1
2 5 5
1 6 4
2 5 5
*/
伪AC代码:
洛谷P4169 天使玩偶 CDQ分治的更多相关文章
- [BZOJ2716] [Violet 3]天使玩偶(CDQ分治)
[BZOJ2716] [Violet 3]天使玩偶(CDQ分治) 题面 Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里, ...
- BZOJ 2716: [Violet 3]天使玩偶( CDQ分治 + 树状数组 )
先cdq分治, 然后要处理点对答案的贡献, 可以以询问点为中心分成4个区域, 然后去掉绝对值(4种情况讨论), 用BIT维护就行了. --------------------------------- ...
- 洛谷P3810 陌上花开(CDQ分治)
洛谷P3810 陌上花开 传送门 题解: CDQ分治模板题. 一维排序,二维归并,三维树状数组. 核心思想是分治,即计算左边区间对右边区间的影响. 代码如下: #include <bits/st ...
- [bzoj] 2716 天使玩偶 || CDQ分治
原题 已知n个点有天使玩偶,有m次操作: 操作1:想起来某个位置有一个天使玩偶 操作2:询问离当前点最近的天使玩偶的曼哈顿距离 显然的CDQ问题,三维分别为时间,x轴,y轴. 但是这道题的问题在于最近 ...
- BZOJ 2716 Violet 3 天使玩偶 CDQ分治
题目大意:初始给定平面上的一个点集.提供两种操作: 1.将一个点增加点集 2.查询距离一个点最小的曼哈顿距离 K-D树是啥...不会写... 我仅仅会CDQ分治 对于一个询问,查询的点与这个点的位置关 ...
- CH 4701 - 天使玩偶 - [CDQ分治]
题目链接:传送门 关于CDQ分治(参考李煜东<算法竞赛进阶指南>): 对于一系列操作,其中的任何一个询问操作,其结果必然等价于:初始值 + 此前所有的修改操作产生的影响. 假设共有 $m$ ...
- 天使玩偶:CDQ分治
这道好(du)题(liu)还是很不错的 挺锻炼代码能力和不断优化 卡常的能力的. 对于 每次询问 我都可以将其分出方向 然后 写 也就是针对于4个方向 左下 左上 右下 右上 这样的话 就成功转换了问 ...
- BZOJ.2716.[Violet3]天使玩偶(CDQ分治 坐标变换)
题目链接 考虑对于两个点a,b,距离为|x[a]-x[b]|+|y[a]-y[b]|,如果a在b的右上,那我们可以把绝对值去掉,即x[a]+y[a]-(x[b]+y[b]). 即我们要求满足x[b]& ...
- [bzoj] 3263 陌上花开 洛谷 P3810 三维偏序|| CDQ分治 && CDQ分治讲解
原题 定义一个点比另一个点大为当且仅当这个点的三个值分别大于等于另一个点的三个值.每比一个点大就为加一等级,求每个等级的点的数量. 显然的三维偏序问题,CDQ的板子题. CDQ分治: CDQ分治是一种 ...
随机推荐
- Oracle增删改查sql语句
--创建表空间 create tablespace waterboss datafile 'd:\waterboss.dbf' size 100m autoextend on next 10m --创 ...
- PHP二维数组(或任意维数组)转换成一维数组的方法汇总(实用)
目录 1 array_reduce函数法 2 array_walk_recursive函数法 3 array_map函数法 假设有下面一个二维数组: $user = array( '0' => ...
- Spring-Boot Banner
下载Spring-Boot源码,目录结构spring-boot-2.1.0.M2\spring-boot-2.1.0.M2\spring-boot-project\spring-boot\src\ma ...
- redis的配置文件解释
redis的守护进行 守护进程(Daemon Process),也就是通常说的 Daemon 进程(精灵进程),是 Linux 中的后台服务进程.它是一个生存期较长的进程,通常独立 于控制终端并且周期 ...
- django restframework PrimaryKeyRelatedField筛选的困惑
一.在开发某运动app时,遇见以下情况 1.部分表内容如下: class Sports(models.Model): ''' 运动表 ''' school = models.ForeignKey(Sc ...
- linux audit审计(8)--开启audit对系统性能的影响
我们使用测试性能的工具,unixbench,它有一下几项测试项目: Execl Throughput 每秒钟执行 execl 系统调用的次数 Pipe Throughput 一秒钟内一个进程向一个管道 ...
- initial
摘自http://blog.csdn.net/liming0931/article/details/7039680 首先说说结构化过程语句,在verilog中有两种结构化的过程语句:initial语句 ...
- 前端使用Javascrip实现图片轮播
Javascript实现网页图片自动轮播 1.创建一个img标签 设置默认图片,以及图片的高度和宽度,为了大家方便,我将CSS样式和JS语句都写在一个html文件中,演示用的图片来自小明官网:'htt ...
- HTML5-Video视频-基础篇
展示视频 视频 <video width=" controls="controls"> <source src="movie.mp4" ...
- github-share报错无法读取远程仓库
报错:github Could not read from remote repository 1.github创建仓库成功,而push报告此错误 2.考虑远程仓库名与本地项目名/文件夹名不匹配 3. ...