题目链接
老 C 是个程序员。
最近老 C 从老板那里接到了一个任务——给城市中的手机基站写个管理系统。
作为经验丰富的程序员,老 C 轻松地完成了系统的大部分功能,并把其中一个功能交给你来实现。
由于一个基站的面积相对于整个城市面积来说非常的小,因此每个的基站都可以看作坐标系中的一个点,其位置可以用坐标 (x,y) 来表示。
此外,每个基站还有很多属性,例如高度、功率等。
运营商经常会划定一个区域,并查询区域中所有基站的信息。
现在你需要实现的功能就是,对于一个给定的矩形区域,回答该区域中(包括区域边界上的)所有基站的功率总和。
如果区域中没有任何基站,则回答 0。
输入格式
第一行两个整数 n,m,表示一共有 n 个基站和 m 次查询。
接下来一共有 n 行,每行由 xi,yi,pi 三个空格隔开的整数构成,表示一个基站的坐标 (xi,yi) 和功率 pi。不会有两个基站位于同一坐标。
接下来一共有 m 行,每行由 x1j,y1j,x2j,y2j 四个空格隔开的整数构成,表示一次查询的矩形区域。该矩形对角坐标为 (x1j,y1j) 和 (x2j,y2j),且 4 边与坐标轴平行。
输出格式
输出 m 行,每行一个整数,对应每次查询的结果。
数据范围
1≤n,m≤105,
−231≤xi,yi,pi,x1j,y1j,x2j,y2j<231,
x1j≤x2j,y1j≤y2j。
输入样例1:
输出样例1:
输入样例2:
输出样例2:
解题思路
cdq分治
增加一个维度 z,z=0 表示计算点,z=1 表示询问点,然后利用二维前缀和计算答案,对于查询的矩形,其四个点都为查询点,然后利用 cdq分治 即可解决此题,另外由于 z 只有两个值:0 或 1,故可以不用树状数组维护第三维的信息,直接用个变量统计 z=0 的信息即可,另外也不需要判重,对于出现相等的点,id 自然会区分且不影响答案
代码
#include <bits/stdc++.h>
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
template <typename T> void inline read(T &x) {
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}
const int N=5e5+5;
int n,m;
LL res[N];
struct A
{
int x,y,z,sign,id;
LL p;
bool operator<(const A &o)const
{
if(x!=o.x)return x<o.x;
if(y!=o.y)return y<o.y;
return z<o.z;
}
}a[N],b[N];
void merge_sort(int l,int r)
{
if(l>=r)return ;
int mid=l+r>>1;
merge_sort(l,mid),merge_sort(mid+1,r);
int i=l,j=mid+1,k=0;
LL res=0;
while(i<=mid&&j<=r)
if(a[i].y<=a[j].y)res+=!a[i].z*a[i].p,b[++k]=a[i++];
else
a[j].p+=a[j].z*res,b[++k]=a[j++];
while(i<=mid)res+=!a[i].z*a[i].p,b[++k]=a[i++];
while(j<=r)a[j].p+=a[j].z*res,b[++k]=a[j++];
for(int i=l,j=1;j<=k;j++,i++)a[i]=b[j];
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i].x>>a[i].y>>a[i].p;
int k=n;
for(int i=1;i<=m;i++)
{
int x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
a[++k]={x2,y2,1,1,i};
a[++k]={x1-1,y1-1,1,1,i};
a[++k]={x2,y1-1,1,-1,i};
a[++k]={x1-1,y2,1,-1,i};
}
sort(a+1,a+1+k);
merge_sort(1,k);
for(int i=1;i<=k;i++)res[a[i].id]+=a[i].z*a[i].p*a[i].sign;
for(int i=1;i<=m;i++)cout<<res[i]<<'\n';
return 0;
}
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!