[BZOJ2716][天使玩偶angel][CDQ分治]
来源:互联网 发布:网络平台合作推广方案 编辑:程序博客网 时间:2024/05/01 10:35
[BZOJ2716][天使玩偶angel][CDQ分治]
题目大意:
先给出n个点, 然后有m个操作, (1, x, y) 表示查询离(x, y)最近点的曼哈顿距离, (2, x, y) 表示插入点 (x, y)。
CDQ分治相关:
这道题在线的话是可以用KD-Tree维护平面上的点集。但是既然题目没有要求在线那就用CDQ分治做好了。
CDQ分治是一种离线的分治算法。对于一个数据结构问题,无非存在两种操作:修改和查询。但是修改和查询往往都是动态的,也就是存在时间维度上的限制,要进行某一个查询,就一定要处理在这个查询之前的所有修改。而CDQ分治可以打破这一维的限制,使得动态查询变为静态查询。用到的方法就是对于一个询问,将它和所有和它有关的修改联系在一起。
(值得注意的是:这一维并不一定是时间上的限制,也有可能是别的。比如BZOJ3262 陌上花开。)
首先我们定义
可以看出,
思路:
容易看出这道题的修改和查询操作分别为1和2。
我们要把和查询有关的修改整理成某个查询的前缀,在这道题里总共有三个限制
考虑到编码方便
右上,左上和右下都可以由原平面水平和竖直翻转得到,只需要编码左下一个方位。
曼哈顿距离的计算方法为:
dist((x,y),(x′,y′))=|x−x′|+|y−y′| ,当只考虑左下方位时可以去掉绝对值,原式转化为dist((x,y),(x′,y′))=x+y−(y′+x′) 。即在询问(x,y) 的所有修改前缀(x′,y′) 中,我们要求Max(x′+y′) 。可以用数组数组维护区间最大值
Q:前面说到CDQ分治只能取消
A:哈,不存在的,
坑:
翻转时要保证翻转后的点集
代码:
#include <bits/stdc++.h>const int Maxn = 1000010;const int INF = 1 << 30;using namespace std;inline int Max(const int &a, const int &b) { return a > b ? a : b;}inline int Min(const int &a, const int &b) { return a < b ? a : b;}inline char get(void) { static char buf[1000000], *p1 = buf, *p2 = buf; if (p1 == p2) { p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin); if (p1 == p2) return EOF; } return *p1++;}inline void read(int &x) { x = 0; static char c; bool minus = false; for (; !(c >= '0' && c <= '9'); c = get()) if (c == '-') minus = true; for (; c >= '0' && c <= '9'; x = x * 10 + c - '0', c = get()); if (minus) x = -x;}struct Abcd { int x, y, k, id; friend bool operator < (const Abcd &a, const Abcd &b) { if (a.x == b.x) return a.id < b.id; else return a.x < b.x; }} oo[Maxn];int n, m, Mx, ans[Maxn], t[Maxn];inline void add(int x, int y) { for (x; x <= Mx; x += x & -x) { t[x] = Max(t[x], y); }}inline int query(int x) { int sum = 0; for (; x; x -= x & -x) { sum = Max(sum, t[x]); } return sum;}inline void clear(int x) { for (x; x <= Mx; x += x & -x) { t[x] = 0; }}struct Cdq { Abcd T[Maxn]; int n; inline void init(const int &n) { this->n = n; sort(oo + 1, oo + 1 + n); } inline void solve(int L, int R) { if (L >= R) return; int mid = (L + R) >> 1, i = L, j = mid + 1; for (int k = L; k <= R; k++) { if (oo[k].id <= mid) T[i++] = oo[k]; else T[j++] = oo[k]; } for (int k = L; k <= R; k++) oo[k] = T[k]; solve(L, mid); i = L, j = mid + 1; for (; j <= R; j++) if (oo[j].k == 2) { for (; i <= mid && oo[i].x <= oo[j].x; i++) if (oo[i].k == 1) { add(oo[i].y, oo[i].x + oo[i].y); } int tmp = query(oo[j].y); if (tmp) ans[oo[j].id] = Min(ans[oo[j].id], oo[j].x + oo[j].y - tmp); } for (j = L; j < i; j++) if (oo[j].k == 1) clear(oo[j].y); solve(mid + 1, R); merge(oo + L, oo + mid + 1, oo + mid + 1, oo + R + 1, T + L); for (int i = L; i <= R; i++) oo[i] = T[i]; }} cdq;int main(void) { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); read(n), read(m); for (int i = 1; i <= n; i++) { read(oo[i].x), read(oo[i].y); Mx = Max(Mx, Max(++oo[i].x, ++oo[i].y)); oo[i].id = i; oo[i].k = 1; } for (int i = n + 1; i <= n + m; i++) { read(oo[i].k), read(oo[i].x), read(oo[i].y); Mx = Max(Mx, Max(++oo[i].x, ++oo[i].y)); oo[i].id = i; } for (int i = 1; i <= n + m; i++) ans[i] = INF; Mx++; cdq.init(n + m); cdq.solve(1, n + m); for (int i = 1; i <= n + m; i++) oo[i].x = Mx - oo[i].x; cdq.init(n + m); cdq.solve(1, n + m); for (int i = 1; i <= n + m; i++) oo[i].y = Mx - oo[i].y; cdq.init(n + m); cdq.solve(1, n + m); for (int i = 1; i <= n + m; i++) oo[i].x = Mx - oo[i].x; cdq.init(n + m); cdq.solve(1, n + m); for (int i = 1; i <= n + m; i++) if (ans[i] != INF) printf("%d\n", ans[i]); return 0;}
完。
By g1n0st
- [BZOJ2716][天使玩偶angel][CDQ分治]
- BZOJ-2716-天使玩偶angel-CDQ分治
- [BZOJ2716][Violet 3]天使玩偶(cdq分治+bit)
- [BZOJ2716][Violet 3]天使玩偶 CDQ分治+树状数组
- BZOJ2716: [Violet 3]天使玩偶(CDQ分治)
- bzoj2716 [Violet 3]天使玩偶(CDQ分治)
- 【Violet3】【BZOJ2716】天使玩偶
- bzoj 2716 天使玩偶 CDQ分治
- bzoj2716: [Violet 3]天使玩偶
- BZOJ 2716 Violet 3 天使玩偶 CDQ分治
- bzoj 2716: [Violet 3]天使玩偶(cdq分治)
- [BZOJ]2716: [Violet 3]天使玩偶 CDQ分治+树状数组
- [BZOJ2716][Violet 3]天使玩偶 && kdtree
- [KDTree] [BZOJ2716] [Violet 3] 天使玩偶
- bzoj2716 [Violet 3]天使玩偶(KDtree)
- 【bzoj 2716】[Violet 3]天使玩偶 (cdq分治+树状数组)
- KD_Tree 【bzoj2648 && bzoj2716】SJY摆棋子 && [voilet 3] 天使玩偶
- bzoj2716 [ Violet 3 ] --cdq分治+树状数组
- 并查集——奇偶性(Parity)
- WinForm嵌入Chrome内核浏览器
- jquey获取页面中所有被选中的checkbox和radio的值,并保存为以逗号隔开的字符串
- Centos 安装 mysql5.1
- 九度OJ-1036:Old Bill
- [BZOJ2716][天使玩偶angel][CDQ分治]
- C++ sscanf函数
- Tensorflow基本使用
- C#中的静态方法和静态变量的一些总结
- Android 禁止Edittext弹出系统软键盘 的几种方法
- JDK8 源码之HashMap(1)
- OPENGL的模板缓冲
- Linux上安装PyLucene
- 解密HLS中的AES加密