洛谷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建表流程
--创建表空间test1 create tablespace test1 datafile 'd:\test1.dbf' size 100m autoextend on next 10m --创建用户 ...
- mybatis两种开发方式
本文首先讲解从JDBC到mybatis的演变过程,然后是使用mybatis进行开发的两种方式. 一 JDBC的使用及其优化 1.使用JDBC进行数据库操作 加载JDBC驱动: 建立并获取数据库连接: ...
- 下拉框插件select2的使用
它的优点有: 样式还算好看,支持多选,支持索搜 下面来介绍下select2的用法 1.最简单的用法 只需要加载css和js即可使用 <select name="" id=&q ...
- java随笔4 java中接参整形转字符串
通过+‘’来实现
- prometheus和metrucs-server (k8s监控)
资源指标:metrucs-server 自定义指标:prometheus, k8s-prometheus-adapter(转换prometheus数据的格式) 新一代架构: 核心指标流水线:由kube ...
- 设计模式笔记:单一职责原则(SRP, Single Responsibility Principle)
1. 单一职责原则核心思想 一个类应该有且只有一个变化的原因. 2. 为什么引入单一职责原则 单一职责原则将不同的职责分离到单独的类,每一个职责都是一个变化的中心. 在SRP中,把职责定义为变化的原因 ...
- CSS单元的位置和层次-div标签
我们都知道,在网页上利用HTML定位文字和图象是一件“令人心痛”的事情.我们必须使用表格标签和隐式GIF图象,即使这样也不能保证定位的精确,因为浏览器和操作平台的不同会使显示的结果发生变化. 而CSS ...
- 不幸,我的Ryzen 7 1700X中招了,也有segfault
在历经了I7-5775C,I7-5820K之后,决定尝鲜用一下为AMD漂亮翻身的Ryzen 7,海淘了一颗Ryzen 7 1700X 最近听说在极重负载的情况下,CPU会出错,于是从网上找来Kill- ...
- 线程同步Volatile与Synchronized(一)
volatile 一.volatile修饰的变量具有内存可见性 volatile是变量修饰符,其修饰的变量具有内存可见性. 可见性也就是说一旦某个线程修改了该被volatile修饰的变量,它会保证修改 ...
- 创建一个UWP 打包签名
Create a certificate for package signing 2017/2/8 3 min to read [ Updated for UWP apps on Windows 10 ...