[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

Sample Output

11
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的任务(扫描线+树状数组)

BZOJ 4822: [Cqoi2017]老C的任务

bzoj4822: [Cqoi2017]老C的任务(扫描线+BIT/线段树)

BZOJ1935/4822[Shoi2007]Tree 园丁的烦恼/[Cqoi2017]老C的任务 树状数组

[BZOJ4824][CQOI2017]老C的键盘(树形DP)

BZOJ 4824: [Cqoi2017]老C的键盘