2847. 老C的任务

题目链接

2847. 老C的任务

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 行,每行一个整数,对应每次查询的结果。

数据范围

1n,m105,
231xi,yi,pi,x1j,y1j,x2j,y2j<231,
x1jx2j,y1jy2j

输入样例1:

4 2 0 0 1 0 1 2 2 2 4 1 0 8 0 0 1 1 1 1 5 6

输出样例1:

11 4

输入样例2:

3 2 -100 0 16 1 -10 32 1000 100 64 0 0 0 1 -1000 -1000 10000 10000

输出样例2:

0 112

解题思路

cdq分治

增加一个维度 zz=0 表示计算点,z=1 表示询问点,然后利用二维前缀和计算答案,对于查询的矩形,其四个点都为查询点,然后利用 cdq 即可解决此题,另外由于 z 只有两个值:01,故可以不用树状数组维护第三维的信息,直接用个变量统计 z=0 的信息即可,另外也不需要判重,对于出现相等的点,id 自然会区分且不影响答案

  • 时间复杂度:O(nlogn)

代码

// Problem: 老C的任务 // Contest: AcWing // URL: https://www.acwing.com/problem/content/2849/ // Memory Limit: 256 MB // Time Limit: 3000 ms // // Powered by CP Editor (https://cpeditor.org) // %%%Skyqwq #include <bits/stdc++.h> //#define int long long #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__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/16782916.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(159)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示