描述

先给出n个点, 然后有m个操作, (1, x, y) 表示查询离(x, y)最近点的曼哈顿距离, (2, x, y) 表示插入点 (x, y).

分析

  • 不会做... 又照着别人的代码打了一遍... CDQ分治总想不到思路
  • 比较关键的几个地方是 : 1. 坐标的范围是小于1000000的所以可以用树状数组维护. 2. 距离点(x, y)最近的点和x的方位有四种, 左下左上右下右上, 然后只考虑一个方位, 另外的改变坐标即可. 3. 曼哈顿距离不是欧几里得距离, 是横纵坐标之差绝对值的和. dis({x, y}, {x', y'}) = |x-x'| + |y-y'|. 在只考虑(x', y')在(x, y)的左下方时, 可以去掉绝对值 : dis = x+y - (x'+y'), 使x'+y'最大即可.
  • 分治时始终保持横坐标递增, 分治时考虑左边对右边的影响, 上面说了要使dis = x+y - (x'+y')的x'+y'最大, 就按 x' 排序按 y' 用树状数组维护x'+y'的最大值. 在树状数组中查询小于y的最大x'+y'值.
代码
#include #include using namespace std;
const int maxn = 1000000 + 10;
const int INF = 1000000000;
int max_x;
int ans[maxn];
struct BIT {
int c[maxn];
int lowbit(int x) {
return x & (-x);
}
void modify(int x, int d) {
while(x <= max_x) {
c[x] = max(c[x], d);
x += lowbit(x);
}
}
int query(int x) {
int ret = 0;
while(x > 0) {
ret = max(ret, c[x]);
x -= lowbit(x);
}
return ret;
}
void clear(int x) {
while(x <= max_x) {
c[x] = 0;
x += lowbit(x);
}
}
} bit;
struct Node {
int x, y, k, id;
bool operator < (const Node& rhs) const {
if(x != rhs.x) return x < rhs.x;
return id < rhs.id;
}
} A[maxn];
#define a A[i]
#define b A[j]
struct CDQ {
int n;
Node T[maxn];
void init(int n) {
this->n = n;
sort(A+1, A+n+1);
}
void solve(int L, int R) {
if(L >= R) return;
int M = (L+R) >> 1;
int i, j, p = L, q = M+1;
for(i = L; i <= R; i++) if(a.id <= M) T[p++] = a; else T[q++] = a;
for(i = L; i <= R; i++) A[i] = T[i];
solve(L, M);
i = M+1; j = L;
for(; i <= R; i++) if(a.k == 2) {
for(; j <= M && b.x <= a.x; j++) if(b.k == 1)
bit.modify(b.y, b.x+b.y);
int t = bit.query(a.y);
if(t) ans[a.id] = min(ans[a.id], a.x+a.y-t);
}
for(i = L; i < j; i++) if(a.k == 1)
bit.clear(a.y);
solve(M+1, R);
merge(A+L, A+M+1, A+M+1, A+R+1, T+L);
for(i = L; i <= R; i++) A[i] = T[i];
}
} cdq;
int main()
{
int n, m;
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++) {
scanf("%d %d", &a.x, &a.y);
a.x++; a.y++; a.id = i; a.k = 1;
max_x = max(max_x, max(a.x, a.y));
}
for(int i = n+1; i <= n+m; i++) {
scanf("%d %d %d", &a.k, &a.x, &a.y);
a.x++; a.y++; a.id = i;
max_x = max(max_x, max(a.x, a.y));
}
max_x++; n += m;
for(int i = 1; i <= n; i++) ans[i] = INF;
cdq.init(n); cdq.solve(1, n);
for(int i = 1; i <= n; i++) a.x = max_x - a.x;
cdq.init(n); cdq.solve(1, n);
for(int i = 1; i <= n; i++) a.y = max_x - a.y;
cdq.init(n); cdq.solve(1, n);
for(int i = 1; i <= n; i++) a.x = max_x - a.x;
cdq.init(n); cdq.solve(1, n);
for(int i = 1; i <= n; i++)
if(ans[i] != INF) printf("%d\n", ans[i]);
return 0;
}

BZOJ-2716-天使玩偶angel-CDQ分治相关推荐

  1. 天使玩偶(CDQ分治+最小曼哈顿距离)

    天使玩偶 题意:有两种操作: 给二维平面上加入一个点 询问二维平面上到某个点最近的一个点(用曼哈顿距离来表示) 思路:标准的CDQ分治,离线处理两种操作 当想到CDQ分治后本题的重点在于如何处理曼哈顿 ...

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

    前言:我们又回到了这道题,不过这次我们选择一个常数小一点的算法:CDQ Description Input Output Sample Input 100 100 81 23 27 16 52 58 ...

  3. BZOJ - 2244 拦截导弹 (dp,CDQ分治+树状数组优化)

    BZOJ - 2244 拦截导弹 (dp,CDQ分治+树状数组优化) 1 #include<algorithm> 2 #include<iostream> 3 #include ...

  4. BZOJ 1176[Balkan2007]Mokia (cdq分治,矩阵加矩阵求和)

    BZOJ 1176[Balkan2007]Mokia (cdq分治,矩阵加矩阵求和) Description 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值. ...

  5. BZOJ 1492: [NOI2007]货币兑换Cash [CDQ分治 斜率优化DP]

    传送门 题意:不想写... 扔链接就跑 好吧我回来了 首先发现每次兑换一定是全部兑换,因为你兑换说明有利可图,是为了后面的某一天两种卷的汇率差别明显而兑换 那么一定拿全利啊,一定比多天的组合好 $f[ ...

  6. bzoj 2244: [SDOI2011]拦截导弹 cdq分治

    2244: [SDOI2011]拦截导弹 Time Limit: 30 Sec  Memory Limit: 512 MBSec  Special Judge Submit: 237  Solved: ...

  7. bzoj 2648 SJY摆棋子 cdq分治+树状数组

    题面 题目传送门 解法 同bzoj2716 自己cdq写的还是丑啊,别人A掉了我T飞了 代码 #include <bits/stdc++.h> #define inf 1 << ...

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

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

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

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

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

最新文章

  1. Python 列表生成式的使用
  2. iOS - 利用 UIBezierPath 绘制圆弧
  3. oracle查询blob数据,C#查询Oracle clob blob数据
  4. 新建了一个英文Blog
  5. 【C++】智能指针简述(五):解决循环引用的weak_ptr
  6. cad移动时捕捉不到基点_硬盘或移动硬盘认不到时,应该怎样进行故障的检测才正确...
  7. 中国剩余定理及其拓展
  8. [Unity][FlowCanvas] FlowScript 实现基础人物移动
  9. SQL 2005数据库函数基本应用
  10. Atitit.项目修改补丁打包工具 使用说明
  11. php本地如何开启websocket遇到的坑
  12. win7共享wifi自动获取不到ip地址的解决办法
  13. python cv2统一缩放图片尺寸,将透明背景填充白色
  14. 施耐德PM5350电度表电能数据解析
  15. 搜狗细胞词库解析(仅提取词和词频)
  16. 【Unity Shader】 Alpha测试
  17. ZYNQ7000 学习(二十五)纯PL 实现独立显存VGA驱动并显示画面
  18. spin_lock_bh想到的一些事
  19. 【无标题】Ds1302驱动代码编写并在Lcd1602液晶显示
  20. IP-guard V4 服务器迁移方法

热门文章

  1. 科大星云诗社动态20210301
  2. 云炬随笔20211010(4)
  3. redis常用命令getex_Redis常用命令(key、string、List)
  4. PIC单片机精通_A/D模数转换模块细节补充
  5. 使用MFC进行编程,绘制直线椭圆以及样条曲线
  6. 函数的多态性以及虚函数
  7. 求1+2+……+N的和
  8. Servlet中如何获取param-name对应的值?
  9. 80x86描述符总结及解析描述符的小程序
  10. Head First JSP---随笔三