还是照着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分治的更多相关文章

  1. [BZOJ2716] [Violet 3]天使玩偶(CDQ分治)

    [BZOJ2716] [Violet 3]天使玩偶(CDQ分治) 题面 Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里, ...

  2. BZOJ 2716: [Violet 3]天使玩偶( CDQ分治 + 树状数组 )

    先cdq分治, 然后要处理点对答案的贡献, 可以以询问点为中心分成4个区域, 然后去掉绝对值(4种情况讨论), 用BIT维护就行了. --------------------------------- ...

  3. 洛谷P3810 陌上花开(CDQ分治)

    洛谷P3810 陌上花开 传送门 题解: CDQ分治模板题. 一维排序,二维归并,三维树状数组. 核心思想是分治,即计算左边区间对右边区间的影响. 代码如下: #include <bits/st ...

  4. [bzoj] 2716 天使玩偶 || CDQ分治

    原题 已知n个点有天使玩偶,有m次操作: 操作1:想起来某个位置有一个天使玩偶 操作2:询问离当前点最近的天使玩偶的曼哈顿距离 显然的CDQ问题,三维分别为时间,x轴,y轴. 但是这道题的问题在于最近 ...

  5. BZOJ 2716 Violet 3 天使玩偶 CDQ分治

    题目大意:初始给定平面上的一个点集.提供两种操作: 1.将一个点增加点集 2.查询距离一个点最小的曼哈顿距离 K-D树是啥...不会写... 我仅仅会CDQ分治 对于一个询问,查询的点与这个点的位置关 ...

  6. CH 4701 - 天使玩偶 - [CDQ分治]

    题目链接:传送门 关于CDQ分治(参考李煜东<算法竞赛进阶指南>): 对于一系列操作,其中的任何一个询问操作,其结果必然等价于:初始值 + 此前所有的修改操作产生的影响. 假设共有 $m$ ...

  7. 天使玩偶:CDQ分治

    这道好(du)题(liu)还是很不错的 挺锻炼代码能力和不断优化 卡常的能力的. 对于 每次询问 我都可以将其分出方向 然后 写 也就是针对于4个方向 左下 左上 右下 右上 这样的话 就成功转换了问 ...

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

  9. [bzoj] 3263 陌上花开 洛谷 P3810 三维偏序|| CDQ分治 && CDQ分治讲解

    原题 定义一个点比另一个点大为当且仅当这个点的三个值分别大于等于另一个点的三个值.每比一个点大就为加一等级,求每个等级的点的数量. 显然的三维偏序问题,CDQ的板子题. CDQ分治: CDQ分治是一种 ...

随机推荐

  1. hashCode和equals的关系分析

    hashCode:说白了,简单的就看做一个函数,但是该函数有可能出现:对于某个x值,存在不止一个y值与之对应.这种情况就叫哈希碰撞. 那么: 1.如果hashCode相等,两个对象不一定是同一个对象( ...

  2. python学习笔记(10)--组合数据类型(集合类型)

    集合类型 集合是多个元素的无序组合,每个元素唯一,不存在相同类型,每个元素是不可变类型.用{}表示,元素间用逗号分隔.建立结合类型用{},或set函数,如果是空集合必须用set. >>&g ...

  3. SCP传送文件时提示No ECDSA host key is known forx.x.x.x and you have requested strict checking.问题的解决办法

    在使用SCP向其他设备传送文件时,打印如下错误: No ECDSA host key is known for x.x.x.x and you have requested strict checki ...

  4. PHP人工智能库

    PHP虽然不是人工智能语言,但做人工智能理论上没问题,下面本人整理了一些PHP人工智能库.1.NLPTools(http://php-nlp-tools.com/)NLPTools是一个PHP自然语言 ...

  5. mybatis generator的maven插件,找不到properties的配置文件错误的解决

    第一次运行的时候,maven插件是正确运行了的 但后面对 maven 的 build节点做了一点修改,就开始报错,找不到 properties标签指定的的数据库连接配置文件了 修改部分如下: 这个操作 ...

  6. fiddler 学习笔记1-下载安装、开启、关闭抓包功能

    1 下载安装(安装于C盘之外的空间中) https://www.telerik.com/fiddler 2 开启抓包功能:安装后默认为开启状态 点击 file-capture 或左下角capture ...

  7. SQL Server 只安装客户端的方法

    只安装管理工具

  8. 获取DataSet中某行某列的数据

    LabelText = DataSet11.Tables("COMM.USERS").Rows[0]["User_Name"].tostring() Label ...

  9. 一、hadoop部署

    一.Java环境 yum 安装方式安装 1.搜索JDK安装包 yum search java|grep jdk 2.安装 yum install java-1.8.0-openjdk-src.x86_ ...

  10. 【python练习题】程序8

    #题目:输出 9*9 乘法口诀表. for i in range(1,10): k = '' for j in range(1,i+1): k += '%s * %s = %s '%(i,j,i*j) ...