不会KD-tree怎么办?CQD硬搞。

建立正常的平面直角坐标系,首先我们只考虑在目标点左下角的点对目标点的贡献,由于左下点的横纵坐标都小于目标点,那么曼哈顿距离就可以化简了,绝对值去掉后,得到$x2+y2-(x1+y1)$,那么我们的目标就转化为了求横纵坐标以及时间轴都小于目标查询点的更改点所作出的贡献,这是一个三维偏序问题,我们在树状数组中维护x+y的最大值,进而即可更新答案。

可是这样做我们只是考虑了左下角点的贡献,肯定是会出错的,但是其余位置的点不容易化简绝对值,或者化简完以后的形式比较难以维护,而且个人认为分类的话码量略大。

那么我们换一个角度,如何将其余位置的点都变化到目标点的左下角。

直接翻转坐标系就行了,把所有点的横纵坐标都翻转一下,使之分别落于其他象限。那么再次调用cdq即可,注意防负下标。

这样打的好处就是比较无脑,而且正确性保障很大,但是常数这种东西还是很神奇的。(本代码不保证Bzoj可A)(其实应该不可A,因为main函数返回值是signed)

#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define int long long
using namespace std;
const int inf=0x7fffffffffffff;
int read(){
int sum=,f=;char x=getchar();
while(x<''||x>''){
if(x=='-') f=-;
x=getchar();
}while(x>=''&&x<=''){
sum=sum*+x-'';
x=getchar();
}return sum*f;
}
struct rec{
int x,y,t,id,ty;
friend bool operator < (const rec &a,const rec &b){
if(a.t==b.t){
if(a.x==b.x) return a.y<b.y;
else return a.x<b.x;
}else return a.t<b.t;
}
}q[],tmp[];
int n,m,kind,Max,ans[],tr[],_time=,mk[];
void change(int pos,int val){
if(!pos) return ;
for(int i=pos;i<=Max;i+=lowbit(i))
if(mk[i]!=_time){
mk[i]=_time;
tr[i]=val;
}
else tr[i]=max(tr[i],val);
}
int ask(int pos){
int ans=-inf;
for(int i=pos;i;i-=lowbit(i))
if(mk[i]==_time) ans=max(ans,tr[i]);
return ans;
}
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+,tot=l;
while(i<=mid&&j<=r){
if(q[i].x<=q[j].x){
tmp[tot]=q[i];
if(!q[i].ty)
change(q[i].y,q[i].x+q[i].y);
++tot;++i;
}else {
tmp[tot]=q[j];
if(q[j].ty)
ans[q[j].id]=min(ans[q[j].id],q[j].x+q[j].y-ask(q[j].y));
++tot;++j;
}
}
while(i<=mid){
tmp[tot]=q[i];
// if(!q[i].ty)
// change(q[i].y,q[i].x+q[i].y);
++tot;++i;
}
while(j<=r){
tmp[tot]=q[j];
if(q[j].ty)
ans[q[j].id]=min(ans[q[j].id],q[j].x+q[j].y-ask(q[j].y));
++tot;++j;
}
/* for(int i=1;i<=Max;i++)
cout<<tr[i]<<" ";cout<<endl;*/
// for(int k=l;k<=mid;k++)
// if(!q[i].ty) del(q[k].y);
/* for(int i=1;i<=Max;i++)
cout<<tr[i]<<" ";cout<<endl;*/
_time++;
// if(_time>=10000000000) _time=1;
for(int k=l;k<=r;k++) q[k]=tmp[k];
}
signed main(){
n=read();m=read();
for(int i=;i<=n;i++){
q[i].x=read()+;q[i].y=read()+;
q[i].t=;q[i].ty=;
Max=max(Max,max(q[i].x,q[i].y));
}
for(int i=;i<=m;i++){
kind=read();
if(kind&){
q[i+n].x=read()+;q[i+n].y=read()+;
q[i+n].t=i;q[i].ty=;
}else {
q[i+n].x=read()+;q[i+n].y=read()+;
q[i+n].t=i;q[i+n].ty=;
q[i+n].id=++ans[];
ans[ans[]]=inf;
}
Max=max(Max,max(q[i+n].x,q[i+n].y));
}n+=m;
// cout<<"Max="<<Max<<endl;
sort(q+,q+n+);
cdq(,n);
/* for(int i=1;i<=n;i++)
cout<<q[i].t<<" "<<q[i].x<<" "<<q[i].y<<endl;*/
for(int i=;i<=n;i++) q[i].x=-q[i].x+Max+;
sort(q+,q++n);
/* for(int i=1;i<=n;i++)
cout<<q[i].t<<" "<<q[i].x<<" "<<q[i].y<<endl;*/
cdq(,n);
for(int i=;i<=n;i++) q[i].y=-q[i].y+Max+;
sort(q+,q++n);
cdq(,n);
for(int i=;i<=n;i++) q[i].x=-q[i].x+Max+;
sort(q+,q+n+);
cdq(,n);
for(int i=;i<=ans[];i++)
printf("%lld\n",ans[i]);
return ;
}

BZOJ2716天使玩偶的更多相关文章

  1. [BZOJ2716]天使玩偶

    [BZOJ2716]天使玩偶 题目大意: 一个平面直角坐标系,坐标\(1\le x,y\le10^6\).\(n(n\le10^6)\)次操作,操作包含以下两种: 新增一个点\((x,y)\): 询问 ...

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

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

  3. bzoj2648SJY摆棋子&&bzoj2716[Violet 3]天使玩偶*

    bzoj2648SJY摆棋子 bzoj2716[Violet 3]天使玩偶 题意: 棋盘上有n个棋子,现在有m个操作,一种是加棋子,一种是查询离某个点最近的棋子.n,m≤500000. 题解: 先将已 ...

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

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

  5. BZOJ2648: SJY摆棋子&&2716: [Violet 3]天使玩偶

    BZOJ2648: SJY摆棋子 BZOJ2716: [Violet 3]天使玩偶 BZOJ氪金无极限... 其实这两道是同一题. 附上2648的题面: Description 这天,SJY显得无聊. ...

  6. BZOJ 2716: [Violet 3]天使玩偶

    2716: [Violet 3]天使玩偶 Time Limit: 80 Sec  Memory Limit: 128 MBSubmit: 1473  Solved: 621[Submit][Statu ...

  7. 【BZOJ-2648&2716】SJY摆棋子&天使玩偶 KD Tree

    2648: SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2459  Solved: 834[Submit][Status][Discu ...

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

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

  9. CH4701 天使玩偶

    题意 4701 天使玩偶 0x40「数据结构进阶」例题 描述 题目PDF 样例输入 2 3 1 1 2 3 2 1 2 1 3 3 2 4 2 样例输出 1 2 来源 石家庄二中Violet 3杯省选 ...

随机推荐

  1. kafka的安装及使用(单节点)

    介绍了linux环境下,kafka 服务的安装与配置 安装 jdk 环境 下载 kafka 源码包放到服务器,解压 开启 zookeeper 开启 kafka server 创建主题 开启生产者 开启 ...

  2. jQuery的显示和隐藏

    在 jQuery 中可以使用 hide() 和 show() 方法来隐藏和显示 HTML 元素,以及使用 toggle() 方法能够切换 hide() 和 show() 方法. 隐藏例子: <! ...

  3. [转]大牛们是怎么阅读 Android 系统源码的

    转自:http://www.zhihu.com/question/19759722 由于工作需要大量修改framework代码, 在AOSP(Android Open Source Project)源 ...

  4. 表格分页——tablePagination

    背景:表格是最为通用的展示方式,为了展示的统一性,以及分页组件的重用,这里写一个分页组件,供比较多或者较少数据2种表格进行分页展示. 分页组件: <template> <el-pag ...

  5. VUe键盘修饰符及自定义指令获取焦点

    首先需要在keyup事件之后. 修饰符 来绑定事件 <body> <div class="box"> <!-- 这里的 @keyup.enter=&q ...

  6. 他爬取了B站所有番剧信息,发现了这些……

    本文来自「楼+ 之数据分析与挖掘实战 」第 4 期学员 -- Yueyec 的作业.他爬取了B站上所有的番剧信息,发现了很多有趣的数据- 关键信息:最高播放量 / 最强up主 / 用户追番数据 / 云 ...

  7. uboot中setenv和saveenv分析

    转:https://blog.csdn.net/weixin_34355715/article/details/85751477 Env在u-boot中通常有两种存在方式,在永久性存储介质中(flas ...

  8. Linux下相关性能指标数据采集

    1)如何查看某个服务进程所占本机物理内存及百分比情况?可以使用Linux命令行查看,也可以使用脚本实现.如下以查看本机kube-nginx服务进程为例: [root@kevin ~]# pidof k ...

  9. Luogu P1294 高手去散步

    Luogu P1294 高手去散步 因为数据较小,所以用邻接矩阵存图即可. 将1号点到$t$号点分别设为起点,深搜遍历路线,开一个$vis$数组,记录每一个点是否被访问过.每次求出从当前起点出发的最大 ...

  10. Gym - 102346D Denouncing Mafia 取k叶子节点使叶子到根覆盖节点数最大

    给你一棵树 你可以取K条链 一条链为根到叶子的路径 问你K条链最多覆盖树上多少个节点 贪心的做 肯定是每次取最长链 但是取完最长链 一颗树就会变为若干个森林 我们要维护当前所有森林里的最长链 ans数 ...