【题目链接】

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=29234

【题意】

询问当前点与已知点的最小曼哈顿距离。

【思路】

CDQ分治

Dist(A,B)=|A.x-B.x|+|A.y-B.y|。假设B处于A点的左下方,则有dist=(A.x+A.y)-(B.x+B.y),然后发现这个就与刚做过的 Mokia 比较相似,只不过是求和变成了求取最大罢了,依然可以对x用cdq分治使升序,对y用树状数组维护统计。

再考虑其它的相对位置就行了。这里有个好(qi)的(ji)方(yin)法(qiao),就是通过把a变成mx-a+1来改变符号的方向,所以只需要写一个处理其中一种情况的函数就可以套用于其他情况了。

【代码】

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define FOR(a,b,c) for(int a=b;a<=c;a++)
using namespace std; const int N = 1e6+;
const int inf = 1e9+; void read(int& x)
{
char c=getchar(); x=; int f=;
while(!isdigit(c)){if(c=='-')f=-; c=getchar();}
while(isdigit(c)) x=x*+c-'',c=getchar();
x*=f;
} int n,m,mx,sz,T,C[N],flag[N]; struct Node {
int t,x,y,pos,ans;
bool operator < (const Node& rhs) const{
return x<rhs.x;
}
Node(int t=,int x=,int y=) {
this->t=t,this->x=x,this->y=y;
pos=sz; ans=inf;
}
}q[N],t[N];
bool cmp(const Node& x,const Node& y)
{
return x.pos<y.pos;
} void upd(int x,int v)
{
for(;x<=mx;x+=x&-x) {
if(flag[x]!=T) flag[x]=T,C[x]=v;
else C[x]=max(C[x],v);
}
}
int query(int x)
{
int res=;
for(;x;x-=x&-x) {
if(flag[x]==T) res=max(res,C[x]);
}
return res;
} void solve(int l,int r)
{
if(l==r) return ;
int mid=(l+r)>>;
int l1=l,l2=mid+,i,j;
for(i=l;i<=r;i++) {
if(q[i].pos<=mid) t[l1++]=q[i];
else t[l2++]=q[i];
}
memcpy(q+l,t+l,sizeof(Node)*(r-l+));
solve(l,mid);
j=l; T++;
for(i=mid+;i<=r;i++) if(q[i].t==) {
for(;j<=mid&&q[j].x<=q[i].x;j++)
if(q[j].t==) upd(q[j].y,q[j].y+q[j].x);
int tmp=query(q[i].y);
if(tmp) q[i].ans=min(q[i].ans,q[i].x+q[i].y-tmp);
}
solve(mid+,r);
l1=l,l2=mid+; int now=l;
while(l1<=mid||l2<=r) {
if(l2>r||l1<=mid&&q[l1]<q[l2]) t[now++]=q[l1++];
else t[now++]=q[l2++];
}
memcpy(q+l,t+l,sizeof(Node)*(r-l+));
} int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
read(n),read(m);
int t,x,y;
FOR(i,,n) {
read(x),read(y);
q[++sz]=Node(,x,y);
mx=max(mx,y);
}
FOR(i,,m) {
read(t),read(x),read(y);
q[++sz]=Node(t,x,y);
mx=max(mx,y);
}
sort(q+,q+sz+);
solve(,sz);
FOR(i,,sz) q[i].x=mx-q[i].x+;
sort(q+,q+sz+);
solve(,sz);
FOR(i,,sz) q[i].y=mx-q[i].y+;
sort(q+,q+sz+);
solve(,sz);
FOR(i,,sz) q[i].x=mx-q[i].x+;
sort(q+,q+sz+);
solve(,sz);
sort(q+,q+sz+,cmp);
FOR(i,n+,sz) if(q[i].t==)
printf("%d\n",q[i].ans);
return ;
}

Ps:手残毁一生 <_<

bzoj 2716 天使玩偶(CDQ分治,BIT)的更多相关文章

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

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

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

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

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

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

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

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2716 怎么KD树跑得都那么快啊..我写的CDQ分治被暴虐 做四遍CDQ分治,每次求一个 ...

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

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

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

  7. bzoj 2716 天使玩偶 —— K-D树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2716 果然和 bzoj 2648 是一样的吧: 只是数组要迷之开大,3e5+5 会RE? 代 ...

  8. 洛谷P4169 天使玩偶 CDQ分治

    还是照着CDQ的思路来. 但是有一些改动: 要求4个方向的,但是可爱的CDQ分治只能求在自己一个角落方向上的.怎么办?旋转!做4次就好了. 统计的不是和,而是——max!理由如下: 设当前点是(x,y ...

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

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

随机推荐

  1. 1014: [JSOI2008]火星人prefix - BZOJ

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...

  2. Windows 2008 R2系统开机时如何不让Windows进行磁盘检测?

    开始→运行,在运行对话框中键入“chkntfs /t:0”,即可将磁盘扫描等待时间设置为0, 如果要在计算机启动时忽略扫描某个分区,比如C盘,可以输入“chkntfs /x c:”命令:如果要恢复对C ...

  3. klayge 4.2.0 编译vc9

    CMake Error at CMakeLists.txt:442 (ADD_PRECOMPILED_HEADER): Unknown CMake command "ADD_PRECOMPI ...

  4. C++函数中那些不可以被声明为虚函数的函数

    转自C++函数中那些不可以被声明为虚函数的函数 常见的不不能声明为虚函数的有:普通函数(非成员函数):静态成员函数:内联成员函数:构造函数:友元函数. 1.为什么C++不支持普通函数为虚函数? 普通函 ...

  5. Eclipse插件—Easy Explorer

    如何使用Eclipse插件—Easy Explorer Easy Explorer是一个Eclipse插件,主要用于快速浏览项目文件的目录,实用性比较强. 使用方法如下:  1.下载Easy Expl ...

  6. xcode 预编译头文件

    xcode 预编译头文件 cocos2d-prefix.pch  #import <Foundation/Foundation.h>

  7. Java泛型:泛型类、泛型接口和泛型方法

    根据<Java编程思想 (第4版)>中的描述,泛型出现的动机在于: 有许多原因促成了泛型的出现,而最引人注意的一个原因,就是为了创建容器类. 泛型类 容器类应该算得上最具重用性的类库之一. ...

  8. [Unity菜鸟] 笔记2 —— 问题篇

    记录在学习<Unity 3.x 游戏开发 经典教材>时遇到的各种问题与笔记 1. 初始不能降低Terrain的高度,需要到Terrain设置的第二个按钮中将Height从0调高 (注意:最 ...

  9. Ubuntu 学习笔记

    1.   ubuntu开启root账号,设置分配很简单,只要为root设置一个root密码就行了: $ sudo passwd root 之后会提示要输入root用户的密码,连续输入root密码,再使 ...

  10. Android EditText属性

    1.EditText输入的文字为密码形式的设置 (1)通过.xml里设置: 把该EditText设为:android:password="true" // 以”.”形式显示文本 ( ...