[bzoj4822][Cqoi2017]老C的任务 树状数组

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

HINT

思维难度:省选

代码难度:省选

算法:树状数组

#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
#define MN 1000000 
#define N 524288
using namespace std;
inline int read()
{
    int x = 0 , f = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
    return x * f;
}
ll Ans[MN+5],t[N*2+5];
int cm=1,n,m,cnt=0,Y[MN+5];
struct Tree{int x,y,z;}T[MN+5];
struct ques{int x,l,r,id,ad;}q[MN*2+5];
bool cmp(ques x,ques y){return x.x<y.x;}
bool cmp2(Tree x,Tree y){return x.x<y.x;}
inline void Renew(int x,int ad){for(t[x+=N]+=ad,x>>=1;x;x>>=1)t[x]=t[x<<1]+t[x<<1|1];}
inline ll Query(int l,int r){
    if(l>r) return 0;ll sum=0;
    for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
    {
        if(~l&1) sum+=t[l+1];
        if( r&1) sum+=t[r-1];    
    }
    return sum;
}
int main(){
    n=read();m=read();
    for(int i=1;i<=n;++i) T[i].x=read(),Y[i]=T[i].y=read(),T[i].z=read();
    sort(Y+1,Y+n+1);
    for(int i=2;i<=n;++i)  if(Y[i]!=Y[i-1]) Y[++cm]=Y[i]; 
    for(int i=1;i<=n;++i) 
        T[i].y=lower_bound(Y+1,Y+cm+1,T[i].y)-Y;
    for(int i=1;i<=m;++i) 
    {
        int X1=read(),Y1=read(),X2=read(),Y2=read();
        Y1=lower_bound(Y+1,Y+cm+1,Y1)-Y;
        Y2=upper_bound(Y+1,Y+cm+1,Y2)-Y-1;
        q[++cnt]=(ques){X1-1,Y1,Y2,i,-1};
        q[++cnt]=(ques){X2,Y1,Y2,i,1};
    }
    sort(q+1,q+cnt+1,cmp);
    sort(T+1,T+n+1,cmp2);
    for(int i=1,j=1;j<=cnt;)
        if(i<=n&&T[i].x<=q[j].x) Renew(T[i].y,T[i].z),++i;
        else Ans[q[j].id]+=q[j].ad*Query(q[j].l,q[j].r),++j;
    for(int i=1;i<=m;++i) printf("%lld\n",Ans[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/LvYanchang/article/details/81738111