参考:http://www.cnblogs.com/slon/archive/2012/03/30/2426104.html

题意:给一个有n个点的点集,有q个询问,每个询问询问一个点p,求与p曼哈顿距离最小的点,并输出曼哈顿距离的最小值。

分析:使得abs(qx - xi) + abs(qy - yi)最小,因为带了个绝对值,所以没法直接套用一些数据结构中查询最值的操作,一时间也没什么头绪。后来看到上面的博客,才明白可以分情况讨论,把绝对值去掉。

一共四种情况:

qx >= xi && qy >= yi

qx >= xi && qy <= yi

qx <= xi && qy >= yi

qx <= xi && qy <= yi

以第一种情况为例分析,其他三种情况分析方法相同。

当 qx > xi && qy > yi 时,直接去绝对值得到:qx - xi + qy - yi = ( qx + qy ) - ( xi +yi ),因为对于每个查询qx + qy相当于一个常数,所以若使qx - xi + qy - yi最小,则 (xi + yi) 最大即可。

于是就转换成了单点更新+区间查最值问题。

线段树离线处理:将点集和查询一块考虑,按上述四种情况分别对点排序,x为第一优先级,y为第二优先级。

将y坐标离散化。

对于每个询问,查询其所属的区间中的最大值。

PS1.其实不用搞四次的,不过这样比较好理解……

PS2.sort函数要仔细考虑一下,跟循环正着跑还是倒着跑有关,之前这里没考虑清楚,样例都跑不对。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm> #define LL long long int
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1 using namespace std; const int MAXN = + ;
const LL INF = 1LL << ; struct node
{
LL x, y;
int id;
void readNode()
{
scanf( "%I64d%I64d", &x, &y );
return;
}
}; bool cmp1( node a, node b )
{
if ( a.x != b.x ) return a.x < b.x;
if ( a.y != b.y ) return a.y < b.y;
return a.id < b.id;
} bool cmp2( node a, node b )
{
if ( a.x != b.x ) return b.x < a.x;
if ( a.y != b.y ) return a.y < b.y;
return b.id < a.id;
} bool cmp3( node a, node b )
{
if ( a.x != b.x ) return b.x < a.x;
if ( a.y != b.y ) return a.y < b.y;
return a.id < b.id;
} bool cmp4( node a, node b )
{
if ( a.x != b.x ) return a.x < b.x;
if ( a.y != b.y ) return a.y < b.y;
return b.id < a.id;
} int N, Q;
int all, cntY;
node D[MAXN];
LL maxi[ MAXN << ];
LL ans[MAXN];
LL hashY[MAXN]; void build( int l, int r, int rt )
{
maxi[rt] = -INF;
if ( l == r ) return;
int m = ( l + r ) >> ;
build( lson );
build( rson );
return;
} void PushUp( int rt )
{
maxi[rt] = max( maxi[rt << ], maxi[rt << | ] );
} void update( LL val, int pos, int l, int r, int rt )
{
if ( l == pos && r == pos )
{
maxi[rt] = max( maxi[rt], val );
return;
}
int m = ( l + r ) >> ;
if ( pos <= m ) update( val, pos, lson );
else update( val, pos, rson );
PushUp( rt );
return;
} LL query( int L, int R, int l, int r, int rt )
{
if ( L <= l && r <= R )
{
return maxi[rt];
} LL res = -INF;
int m = ( l + r ) >> ;
if ( L <= m ) res = max( res, query( L, R, lson ) );
if ( R > m ) res = max( res, query( L, R, rson ) );
return res;
} void init()
{
for ( int i = ; i < N; ++i )
{
D[i].readNode();
D[i].id = -;
hashY[i] = D[i].y;
}
scanf( "%d", &Q );
for ( int i = ; i < Q; ++i )
{
D[ N + i ].readNode();
D[ N + i ].id = i;
hashY[ N + i ] = D[N + i].y;
ans[i] = INF;
} all = N + Q;
sort( hashY, hashY + all );
cntY = unique( hashY, hashY + all ) - hashY;
return;
} int main()
{int cas = ;
while ( scanf( "%d", &N ), N != - )
{
init();
build( , cntY, );
sort( D, D + all, cmp1 ); for ( int i = ; i < all; ++i )
{
int id = lower_bound( hashY, hashY + cntY, D[i].y ) - hashY;
++id;
if ( D[i].id == - ) update( D[i].x + D[i].y, id, , cntY, );
else
{
ans[ D[i].id ] = min( ans[ D[i].id ], D[i].x + D[i].y - query( , id, , cntY, ) );
}
} build( , cntY, );
sort( D, D + all, cmp2 );
for ( int i = all - ; i >= ; --i )
{
int id = lower_bound( hashY, hashY + cntY, D[i].y ) - hashY;
++id;
if ( D[i].id == - ) update( D[i].x - D[i].y, id, , cntY, );
else
{
ans[ D[i].id ] = min( ans[ D[i].id ], D[i].x - D[i].y - query( id, cntY, , cntY, ) );
}
} build( , cntY, );
sort( D, D + all, cmp3 );
for ( int i = ; i < all; ++i )
{
int id = lower_bound( hashY, hashY + cntY, D[i].y ) - hashY;
++id;
if ( D[i].id == - ) update( D[i].y - D[i].x, id, , cntY, );
else
{
ans[ D[i].id ] = min( ans[ D[i].id ], D[i].y - D[i].x - query( , id, , cntY, ) );
}
} build( , cntY, );
sort( D, D + all, cmp4 );
for ( int i = all - ; i >= ; --i )
{
int id = lower_bound( hashY, hashY + cntY, D[i].y ) - hashY;
++id;
if ( D[i].id == - ) update( -D[i].x - D[i].y, id, , cntY, );
else
{
ans[ D[i].id ] = min( ans[ D[i].id ], -D[i].x - D[i].y - query( id, cntY, , cntY, ) );
}
} if ( cas ) puts("");
for ( int i = ; i < Q; ++i )
printf( "%I64d\n", ans[i] );
++cas;
}
return ;
}

HDU 4189 Cybercrime Donut Investigation 线段树+思路的更多相关文章

  1. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  2. HDU.5692 Snacks ( DFS序 线段树维护最大值 )

    HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...

  3. HDU.1556 Color the ball (线段树 区间更新 单点查询)

    HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...

  4. HDU.1166 敌兵布阵 (线段树 单点更新 区间查询)

    HDU.1166 敌兵布阵 (线段树 单点更新 区间查询) 题意分析 加深理解,重写一遍 代码总览 #include <bits/stdc++.h> #define nmax 100000 ...

  5. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  6. HDU.1689 Just a Hook (线段树 区间替换 区间总和)

    HDU.1689 Just a Hook (线段树 区间替换 区间总和) 题意分析 一开始叶子节点均为1,操作为将[L,R]区间全部替换成C,求总区间[1,N]和 线段树维护区间和 . 建树的时候初始 ...

  7. hdu 1754 I Hate It 线段树 点改动

    // hdu 1754 I Hate It 线段树 点改动 // // 不多说,裸的点改动 // // 继续练 #include <algorithm> #include <bits ...

  8. hdu 1166 敌兵布阵 线段树 点更新

    // hdu 1166 敌兵布阵 线段树 点更新 // // 这道题裸的线段树的点更新,直接写就能够了 // // 一直以来想要进线段树的坑,结果一直没有跳进去,今天算是跳进去吧, // 尽管十分简单 ...

  9. R - Weak Pair HDU - 5877 离散化+权值线段树+dfs序 区间种类数

    R - Weak Pair HDU - 5877 离散化+权值线段树 这个题目的初步想法,首先用dfs序建一颗树,然后判断对于每一个节点进行遍历,判断他的子节点和他相乘是不是小于等于k, 这么暴力的算 ...

随机推荐

  1. express_webpack自动刷新

    现在,webpack可以说是最流行的模块加载器(module bundler).一方面,它为前端静态资源的组织和管理提供了相对较完善的解决方案,另一方面,它也很大程度上改变了前端开发的工作流程.在应用 ...

  2. 简单使用mybatis(idea中使用)

    首先创建一个maven项目 第一步:在pom.xml中添加依赖 <dependencies> <!--mybatis--> <dependency> <gro ...

  3. powerdesigner15 反向工程

  4. ECMAscript6(ES6)新特性语法总结(一)

    ES6/ES2015,,在ES5的基础上扩展了很多新的功能,在使用的时候要慎重,因为有一部分js代码在部分浏览器是不兼容的,但是所有写在服务器端的代码基本上都支持ES6的写法. 新特性: 一.开启严格 ...

  5. OCCI结果集(ResultSet)性能优化

    对于ResultSet类中的next()方法,默认是一次检索一行数据,及一次检索执行一次网络往返,当结果集数量大时,效率低:对此OCCI提供了几种改善方法,即:在一次网络往返返回多行数据. 1. 通过 ...

  6. LArea 微信端 地址选择

    最近做到一个项目,微信端的商城需要地址选择功能 在百度上看了,采用LArea.js....下载实例,在移动端模拟器上运行是比较好的, 在微信上模拟后出现很多问题, 1,出现undefined 都定义正 ...

  7. Go单元测试与基准测试

    Go单元测试 Go单元测试框架,遵循规则整理如下: 1.文件命名规则: 含有单元测试代码的go文件必须以_test.go结尾,Go语言测试工具只认符合这个规则的文件 单元测试文件名_test.go前面 ...

  8. php图片压缩-高清晰度

    php高清晰度无损压缩 经常会用到把上传的大图片压缩,特别是体积,在微信等APP应用上,也默认都是有压缩的,那么,怎么样对图片大幅度压缩却仍能保持较高的清晰度呢? 压缩通常是有按比例缩放,和指定宽度压 ...

  9. php 图片操作类,支持生成缩略图,添加水印,上传缩略图

    <?php class Image {     //类开始     public $originimage = ""; //源图片文件地址     public $image ...

  10. 01 mysql 基础一 (进阶)

    mysql基础一 1.认识mysql与创建用户 01 Mysql简介 Mysql是最流行的关系型数据库管理系统之一,由瑞典MySQLAB公司开发,目前属于Oracle公司. MySQL是一种关联数据库 ...