luogu

题意

一个平面上有\(n\)个点,\(m\)次操作,每次新增一个点,或者是询问离某个点最近的点的距离。这里的距离是曼哈顿距离。

\(n,m\le3*10^5\)

sol

写一发\(CDQ\)。

只考虑询问点在其他点的右上方的情况,假设询问点是\(A\),那么所求的距离就是\((X_A-X_i)+(Y_A-Y_i)=(X_A+Y_A)-(X_i+Y_i)\)。

所以我们只需要找出满足\(X_i \le X_A,Y_i \le Y_A\)中\(X_i+Y_i\)的最大值就好了。

\(CDQ\)前先按时间戳排序,向上归并时按\(X\)排序。考虑左边对右边的贡献时,按\(Y\)值为下标插入树状数组,然后查询前缀最大值。

对于不在右上方的情况,只要把坐标轴翻转四次就可以了。

然而。
这题卡常。
以下是一些卡常技巧。
>清空树状数组的时候,如果当前位已经是$0$就直接$return$。
预先记录按照时间戳的排序,每次$CDQ$完后直接复制一遍,不需要排序。
删除不必要的点(不会被任何询问考虑到的点)

常数巨大无比。

code

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
const int N = 1e6+5;
struct node{
int tim,opt,x,y;
bool operator < (const node &b) const
{
if (x!=b.x) return x<b.x;
if (y!=b.y) return y<b.y;
return opt<b.opt;
}
}a[N],p[N],q[N];
int n,m,X,Y,c[N],ans[N];
inline void modify(int k,int v){while(k<=Y)c[k]=max(c[k],v),k+=k&-k;}
inline int query(int k){int s=0;while(k)s=max(s,c[k]),k-=k&-k;return s;}
inline void clear(int k){while(k<=Y)if(c[k])c[k]=0,k+=k&-k;else return;}
void CDQ(int l,int r)
{
if (l==r) return;
int mid=l+r>>1;CDQ(l,mid);CDQ(mid+1,r);
int L=l,R=mid+1;
for (int i=l;i<=r;++i)
if (L<=mid&&(R>r||p[L]<p[R]))
{
q[i]=p[L++];
if (q[i].opt==1) modify(q[i].y,q[i].x+q[i].y);
}
else
{
q[i]=p[R++];
if (q[i].opt==2)
{
int tmp=query(q[i].y);
if (tmp) ans[q[i].tim]=min(ans[q[i].tim],q[i].x+q[i].y-tmp);
}
}
for (int i=l;i<=r;++i) p[i]=q[i],clear(p[i].y);
}
void Delete()
{
int xx=0,yy=0;m=0;
for (int i=1;i<=n;++i)
if (p[i].opt==2)
xx=max(xx,p[i].x),yy=max(yy,p[i].y);
for (int i=1;i<=n;++i)
if (p[i].x<=xx&&p[i].y<=yy)
q[++m]=p[i];
for (int i=1;i<=m;++i) p[i]=q[i];
}
int main()
{
n=gi();m=gi();memset(ans,63,sizeof(ans));
for (int i=1;i<=n;++i)
{
a[i]=(node){0,1,gi()+1,gi()+1};
X=max(X,a[i].x);Y=max(Y,a[i].y);
}
for (int i=1;i<=m;++i)
{
a[++n]=(node){i,gi(),gi()+1,gi()+1};
X=max(X,a[n].x);Y=max(Y,a[n].y);
}
++X;++Y;
for (int i=1;i<=n;++i) p[i]=a[i];
Delete();CDQ(1,m);
for (int i=1;i<=n;++i) p[i]=a[i],p[i].x=X-p[i].x;
Delete();CDQ(1,m);
for (int i=1;i<=n;++i) p[i]=a[i],p[i].y=Y-p[i].y;
Delete();CDQ(1,m);
for (int i=1;i<=n;++i) p[i]=a[i],p[i].x=X-p[i].x,p[i].y=Y-p[i].y;
Delete();CDQ(1,m);
for (int i=1;i<=n;++i) if (a[i].opt==2) printf("%d\n",ans[a[i].tim]);
return 0;
}

[Luogu4169][Violet]天使玩偶/SJY摆棋子的更多相关文章

  1. luogu4169 [Violet]天使玩偶/SJY摆棋子 / bzoj2648 SJY摆棋子 k-d tree

    k-d tree + 重构的思想,就能卡过luogu和bzoj啦orz #include <algorithm> #include <iostream> #include &l ...

  2. bzoj2716/2648 / P4169 [Violet]天使玩偶/SJY摆棋子

    P4169 [Violet]天使玩偶/SJY摆棋子 k-d tree 模板 找了好几天才发现输出优化错了....真是zz...... 当子树非常不平衡时,就用替罪羊树的思想,拍扁重建. luogu有个 ...

  3. 【LG4169】[Violet]天使玩偶/SJY摆棋子

    [LG4169][Violet]天使玩偶/SJY摆棋子 题面 洛谷 题解 至于\(cdq\)分治的解法,以前写过 \(kdTree\)的解法好像还\(sb\)一些 就是记一下子树的横.纵坐标最值然后求 ...

  4. 洛谷 P4169 [Violet]天使玩偶/SJY摆棋子 解题报告

    P4169 [Violet]天使玩偶/SJY摆棋子 题目描述 \(Ayu\)在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,\(Ayu\) 却忘了她把天使玩偶埋在了哪 ...

  5. luoguP4169 [Violet]天使玩偶/SJY摆棋子 K-Dtree

    P4169 [Violet]天使玩偶/SJY摆棋子 链接 luogu 思路 luogu以前用CDQ一直过不去. bzoj还是卡时过去的. 今天终于用k-dtree给过了. 代码 #include &l ...

  6. 洛谷P4169 [Violet]天使玩偶/SJY摆棋子(CDQ分治)

    [Violet]天使玩偶/SJY摆棋子 题目传送门 解题思路 用CDQ分治开了氧气跑过. 将输入给的顺序作为第一维的时间,x为第二维,y为第三维.对于距离一个询问(ax,ay),将询问分为四块,左上, ...

  7. [Violet]天使玩偶/SJY摆棋子 [cdq分治]

    P4169 [Violet]天使玩偶/SJY摆棋子 求离 \((x,y)\) 最近点的距离 距离的定义是 \(|x1-x2|+|y1-y2|\) 直接cdq 4次 考虑左上右上左下右下就可以了-略微卡 ...

  8. P4169 [Violet]天使玩偶/SJY摆棋子

    题目背景 感谢@浮尘ii 提供的一组hack数据 题目描述 Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里,所以她决定仅 ...

  9. LG4169 [Violet]天使玩偶/SJY摆棋子

    题意 Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里,所以她决定仅凭一点模糊的记忆来寻找它. 我们把 Ayu 生活的小镇 ...

随机推荐

  1. 【JavaScript】写代码前的准备

    1.搭建开发环境,编辑器推荐HBuilder,浏览器用谷歌. 2.编写一个HelloWorld程序. HelloWorld.html <!DOCTYPE html> <html> ...

  2. LVS管理工具--ipvsadm

    一. ipvsadm工具介绍 从2.4版本开始,linux内核默认支持LVS.要使用LVS的能力,只需安装一个LVS的管理工具:ipvsadm. LVS的结构主要分为两部分: 工作在内核空间的IPVS ...

  3. Microsoft.VisualStudio.Web.PageInspector.Loader

    未能加载文件或程序集"Microsoft.VisualStudio.Web.PageInspector.Loader, Version=1.0.0.0, Culture=neutral, P ...

  4. java常见异常(更新中)

    Java的异常分为两种,一种是运行时异常(RuntimeException),一种是非运行异常也叫检查式异常(CheckedException) .NullPointerException 空指针异常 ...

  5. Hibernate的一级缓存、二级缓存和查询缓存。

    Hibernate的Session提供了一级缓存的功能,默认总是有效的,当应用程序保存持久化实体.修改持久化实体时,Session并不会立即把这种改变提交到数据库,而是缓存在当前的Session中,除 ...

  6. DIKW:数据、信息、知识、智慧的金字塔层次体系

    http://www.ciotimes.com/ProCase/85417.html 前言 知识对于个人.组织的重要性已经不言而喻.可以说,管理与应用知识的能力已经成为企业的核心竞争力. 知识如此重要 ...

  7. WebUploader 解决文件多次上传和删除上传文件的问题

    文件多次上传有两种情况: 1. 上传前的多次选择 2. 上传成功后,再次选择 其实API上,已经有了介绍了,不知道为什么有同学还是不知道如何做,我来抛砖引玉吧. 配置项: duplicate {Boo ...

  8. 基本sql查询语句练习

    Student(S#,Sname,Sage,Ssex) 学生表  Course(C#,Cname,T#) 课程表  SC(S#,C#,score) 成绩表  Teacher(T#,Tname) 教师表 ...

  9. codeforces 816B.Karen and Coffee 解题报告

    题目链接:http://codeforces.com/contest/816/problem/B 题目意思:给出 n 个recipes,第 i 个(1<= i <=n)recipes 表明 ...

  10. MFC--自定义CMFCTabCtrl的实现

    在MFC实现桌面程序时,可能会用到TabView效果,我实现的是最基本的效果,如下图: 下面介绍详细的实现过程,如果需要效果更好看些,自行美化. 1.  创建自定义MFCTabCtrl类MyMFCTa ...