博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj1935 [SHOI2007]Tree 园丁的烦恼
阅读量:7035 次
发布时间:2019-06-28

本文共 3343 字,大约阅读时间需要 11 分钟。

静态询问平面点数

\(x_i,\ y_i\in[0,\ 10^7],\ n,\ m\leq5\times10^5\)

二维偏序,cdq分治


可以直接 cdq分治,也可以离散化后用 BIT 做、、注意排序时若 \(x,\ y\) 相同,要将点放在询问前面

时间复杂度 \(O(n\log n)\)

代码

cdq分治

#include 
using namespace std;#define nc getchar()const int maxn = 5e5 + 10;int n, m, len, ans[maxn];struct node { int x, y, val, tid; node(int _x = 0, int _y = 0, int _v = 0, int _t = 0) : x(_x), y(_y), val(_v), tid(_t) {} bool operator < (const node& o) const { return x == o.x ? y == o.y ? !val : y < o.y : x < o.x; }} a[maxn * 5], b[maxn * 5];inline int read() { int x = 0; char c = nc; while (c < 48) c = nc; while (c > 47) x = x * 10 + c - 48, c = nc; return x;}void cdq(int l, int r) { if (l == r) return; int mid = (l + r) >> 1; cdq(l, mid), cdq(mid + 1, r); for (int p = l, p1 = l, p2 = mid + 1, s = 0; p <= r; p++) { if (p2 > r || (p1 <= mid && a[p1].y <= a[p2].y)) { s += !a[p1].val, b[p] = a[p1++]; } else { ans[a[p2].tid] += a[p2].val * s, b[p] = a[p2++]; } } for (int i = l; i <= r; i++) { a[i] = b[i]; }}int main() { n = read(), m = read(); for (int i = 1; i <= n; i++) { a[i].x = read(), a[i].y = read(); } len = n; for (int i = 1; i <= m; i++) { int x1 = read(), y1 = read(); int x2 = read(), y2 = read(); a[++len] = node(x2, y2, 1, i); a[++len] = node(x1 - 1, y2, -1, i); a[++len] = node(x2, y1 - 1, -1, i); a[++len] = node(x1 - 1, y1 - 1, 1, i); } sort(a + 1, a + len + 1), cdq(1, len); for (int i = 1; i <= m; i++) { printf("%d\n", ans[i]); } return 0;}

BIT

#include 
using namespace std;#define nc getchar()#define get_val(x) (lower_bound(data + 1, data + tot + 1, x) - data)const int maxn = 5e5 + 10;int n, m, len, tot, ans[maxn], data[maxn * 5], c[maxn * 5];struct Query { int x, y, val, tid; Query(int _x = 0, int _y = 0, int _v = 0, int _t = 0) : x(_x), y(_y), val(_v), tid(_t) {} inline bool operator < (const Query& o) const { return x == o.x ? y == o.y ? !val : y < o.y : x < o.x; }} Q[maxn * 5];inline int read() { int x = 0; char c = nc; while (c < 48) c = nc; while (c > 47) x = (x << 3) + (x << 1) + (c ^ 48), c = nc; return x;}inline void add(int pos) { for (; pos <= tot; pos += pos & -pos) { c[pos]++; }}inline int query(int pos) { int res = 0; for (; pos; pos &= pos - 1) { res += c[pos]; } return res;}int main() { n = read(), m = read(); for (int i = 1; i <= n; i++) { data[++tot] = Q[i].x = read(); data[++tot] = Q[i].y = read(); } len = n; for (int i = 1; i <= m; i++) { int x1 = read(), y1 = read(); int x2 = read(), y2 = read(); if (x1) data[++tot] = x1 - 1; if (y1) data[++tot] = y1 - 1; data[++tot] = x2, data[++tot] = y2; Q[++len] = Query(x2, y2, 1, i); if (x1) Q[++len] = Query(x1 - 1, y2, -1, i); if (y1) Q[++len] = Query(x2, y1 - 1, -1, i); if (x1 && y1) Q[++len] = Query(x1 - 1, y1 - 1, 1, i); } sort(data + 1, data + tot + 1); tot = unique(data + 1, data + tot + 1) - data - 1; for (int i = 1; i <= len; i++) { Q[i].x = get_val(Q[i].x); Q[i].y = get_val(Q[i].y); } sort(Q + 1, Q + len + 1); for (int i = 1; i <= len; i++) { if (Q[i].val) { ans[Q[i].tid] += Q[i].val * query(Q[i].y); } else { add(Q[i].y); } } for (int i = 1; i <= m; i++) { printf("%d\n", ans[i]); } return 0;}

转载于:https://www.cnblogs.com/Juanzhang/p/10647834.html

你可能感兴趣的文章
Flume
查看>>
php instanceof
查看>>
Android第十四天
查看>>
drupal 后台路径
查看>>
移动安全新时代 Chinasec起名赢iPad2
查看>>
V2X项目小结
查看>>
学习笔记---乐观锁 悲观锁 死锁
查看>>
如何避免windows电脑假死机
查看>>
Kotlin整合Vertx开发Web应用
查看>>
在7层分发中,http,mysql是如何控制数据包的走向
查看>>
人生路漫漫
查看>>
双机热备软件在Linux环境下的配置方法
查看>>
美丽的英文诗句【2】
查看>>
DATAGUARD ORA-01274 ORA-01111处理
查看>>
oracle 11g for suse 11g sp2
查看>>
Java基础学习总结(8)——super关键字
查看>>
洛谷1156 垃圾陷阱
查看>>
Java基础学习总结(10)——static关键字
查看>>
Centos6编译安装LAMP(fast-cgi方式)加速的WordPress应用
查看>>
php实现的一个ajax分页数据
查看>>