老 C 是个程序员。
最近老 C 从老板那里接到了一个任务——给城市中的手机基站写个管理系统。作为经验丰富的程序员,老 C 轻松
地完成了系统的大部分功能,并把其中一个功能交给你来实现。由于一个基站的面积相对于整个城市面积来说非常
的小,因此每个的基站都可以看作坐标系中的一个点,其位置可以用坐标(x, y)来表示。此外,每个基站还有很多属
性,例如高度、功率等。运营商经常会划定一个区域,并查询区域中所有基站的信息。现在你需要实现的功能就是,
对于一个给定的矩形区域,回答该区域中(包括区域边界上的)所有基站的功率总和。如果区域中没有任何基站,则回
答 0。
第一行两个整数 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。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
struct node
{
int x;
int y;
int num;
int cnt;
int v;
}s[10000010];
int n,m;
ll v[10000010];
int a,b,c,d;
int g[10000010];
int maxy;
int tot;
ll ans[2000010][5];
void add(int x,int k)
{
for(int i=x;i<=maxy;i+=i&-i)
{
v[i]+=1ll*k;
}
}
ll ask(int x)
{
ll res=0;
for(int i=x;i;i-=i&-i)
{
res+=v[i];
}
return res;
}
bool cmp(node a,node b)
{
if(a.x==b.x)
{
if(a.y==b.y)
{
return a.cnt<b.cnt;
}
return a.y<b.y;
}
return a.x<b.x;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].v);
g[i]=s[i].y;
}
tot=n;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
s[++tot].x=a-1;
s[tot].y=b-1;
s[tot].cnt=i;
s[tot].num=1;
g[tot]=b-1;
s[++tot].x=a-1;
s[tot].y=d;
s[tot].cnt=i;
s[tot].num=2;
g[tot]=d;
s[++tot].x=c;
s[tot].y=b-1;
s[tot].cnt=i;
s[tot].num=3;
g[tot]=b-1;
s[++tot].x=c;
s[tot].y=d;
s[tot].cnt=i;
s[tot].num=4;
g[tot]=d;
}
sort(g+1,g+1+tot);
sort(s+1,s+1+tot,cmp);
maxy=unique(g+1,g+1+tot)-g-1;
for(int i=1;i<=tot;i++)
{
if(!s[i].cnt)
{
int val=lower_bound(g+1,g+1+maxy,s[i].y)-g;
add(val,s[i].v);
}
else
{
int val=lower_bound(g+1,g+1+maxy,s[i].y)-g;
ans[s[i].cnt][s[i].num]=ask(val);
}
}
for(int i=1;i<=m;i++)
{
printf("%lld\n",ans[i][4]+ans[i][1]-ans[i][2]-ans[i][3]);
}
}