[BZOJ4822][Cqoi2017]老C的任务
Posted Elder_Giang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ4822][Cqoi2017]老C的任务相关的知识,希望对你有一定的参考价值。
4822: [Cqoi2017]老C的任务
Time Limit: 20 Sec Memory Limit: 512 MB Submit: 346 Solved: 184 [Submit][Status][Discuss]Description
老 C 是个程序员。
最近老 C 从老板那里接到了一个任务——给城市中的手机基站写个管理系统。作为经验丰富的程序员,老 C 轻松
地完成了系统的大部分功能,并把其中一个功能交给你来实现。由于一个基站的面积相对于整个城市面积来说非常
的小,因此每个的基站都可以看作坐标系中的一个点,其位置可以用坐标(x, y)来表示。此外,每个基站还有很多属
性,例如高度、功率等。运营商经常会划定一个区域,并查询区域中所有基站的信息。现在你需要实现的功能就是,
对于一个给定的矩形区域,回答该区域中(包括区域边界上的)所有基站的功率总和。如果区域中没有任何基站,则回
答 0。
Input
第一行两个整数 n, m,表示一共有n个基站和m次查询。
接下来一共有 n 行,每行由x_i , y_i , p_i 三个空格隔开的整数构成,表示一个基站的坐标(x_i , y_i )和功率p
_i 。不会有两个基站位于同一坐标。
接下来一共有m行,每行由x1_j , y1_j , x2_j , y2_j 四个空格隔开的整数构成,表示一次查询的矩形区域。该矩
形对角坐标为(x1_j , y1_j )和(x2_j , y2_j ),且 4 边与坐标轴平行。
2^31 ≤ x_i , y_i , p_i , x1_j , y1_j , x2_j , y2_j < 2^31, x1_j ≤ x2_j, y1_j ≤ y2_j。
Output
输出 m 行,每行一个整数,对应每次查询的结果。
Sample Input
4 2
0 0 1
0 1 2
2 2 4
1 0 8
0 0 1 1
1 1 5 6
0 0 1
0 1 2
2 2 4
1 0 8
0 0 1 1
1 1 5 6
Sample Output
11
4
4
把询问拆成四个,然后把所有点和询问分别按照$x$排序,$y$离散化,然后树状数组维护即可
#include <cstdio> #include <algorithm> using namespace std; char buf[10000000], *ptr = buf - 1; inline int readint(){ int f = 1, n = 0; char ch = *++ptr; while(ch < ‘0‘ || ch > ‘9‘){ if(ch == ‘-‘) f = -1; ch = *++ptr; } while(ch <= ‘9‘ && ch >= ‘0‘){ n = (n << 1) + (n << 3) + ch - ‘0‘; ch = *++ptr; } return f * n; } typedef long long ll; const int maxn = 100000 + 10, maxm = 100000 + 10; int numy[maxn], ycnt; ll arr[maxn] = {0}; inline void Update(int w, int val){ for(; w <= ycnt; w += w & -w) arr[w] += val; } inline ll Query(int w){ ll s = 0; for(; w; w -= w & -w) s += arr[w]; return s; } struct Node{ int x, y, p; Node(){} bool operator < (const Node &rhs) const { return x < rhs.x; } }no[maxn]; struct Que{ int x, y, id, type; Que(){} Que(int _x, int _y, int _i, int _t): x(_x), y(_y), id(_i), type(_t){} bool operator < (const Que &rhs) const { return x < rhs.x; } }q[maxm * 4]; ll ans[maxm] = {0}; int main(){ fread(buf, sizeof(char), sizeof(buf), stdin); int n, m; n = readint(); m = readint(); for(int x, y, p, i = 1; i <= n; i++){ no[i].x = readint(); numy[i] = no[i].y = readint(); no[i].p = readint(); } sort(no + 1, no + n + 1); sort(numy + 1, numy + n + 1); ycnt = unique(numy + 1, numy + n + 1) - (numy + 1); for(int i = 1; i <= n; i++) no[i].y = lower_bound(numy + 1, numy + ycnt + 1, no[i].y) - numy; for(int x1, y1, x2, y2, i = 1; i <= m; i++){ x1 = readint(); y1 = lower_bound(numy + 1, numy + ycnt + 1, readint()) - numy; x2 = readint(); y2 = upper_bound(numy + 1, numy + ycnt + 1, readint()) - numy - 1; q[i] = Que(x2, y2, i, 1); q[i + m] = Que(x1 - 1, y1 - 1, i, 1); q[i + 2 * m] = Que(x1 - 1, y2, i, 2); q[i + 3 * m] = Que(x2, y1 - 1, i, 2); } sort(q + 1, q + 4 * m + 1); int aa = 1, bb = 1; while(aa <= n && bb <= 4 * m){ if(no[aa].x <= q[bb].x){ Update(no[aa].y, no[aa].p); aa++; } else{ if(q[bb].type == 1) ans[q[bb].id] += Query(q[bb].y); else ans[q[bb].id] -= Query(q[bb].y); bb++; } } while(bb <= 4 * m){ if(q[bb].type == 1) ans[q[bb].id] += Query(q[bb].y); else ans[q[bb].id] -= Query(q[bb].y); bb++; } for(int i = 1; i <= m; i++) printf("%lld\n", ans[i]); return 0; }
以上是关于[BZOJ4822][Cqoi2017]老C的任务的主要内容,如果未能解决你的问题,请参考以下文章
[BZOJ4822][CQOI2017]老C的任务(扫描线+树状数组)
bzoj4822: [Cqoi2017]老C的任务(扫描线+BIT/线段树)
BZOJ1935/4822[Shoi2007]Tree 园丁的烦恼/[Cqoi2017]老C的任务 树状数组