4822: [Cqoi2017]老C的任务
Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 284 Solved: 152
[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
0 0 1
0 1 2
2 2 4
1 0 8
0 0 1 1
1 1 5 6
Sample Output
11
4
4
——————————————————————
这道题明显的扫描线QAQ 数据范围没给就开大了点
横纵坐标 x y 离散化x 按 y 排序 然后按 y 扫一遍就好了
无形卡常最为致命QAQ
这里我还是贴一波正常版的吧 23333
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int M=1e6+7; LL read(){ LL ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } LL ans[M],s[3*M],xs[3*M]; int n,m,xp,qp,ep; int lowbit(int x){return x&-x;} void add(int x,LL v){ while(x<=xp){ s[x]+=v; x+=lowbit(x); } } LL query(int x){ LL ans=0; while(x){ ans+=s[x]; x-=lowbit(x); } return ans; } struct Q{ LL l,r,h,id,s; bool operator <(const Q& x)const{return h<x.h;} void calc(){ ans[id]+=(query(r)-query(l-1))*s; } }q[2*M]; struct pos{ LL x,y,w; bool operator <(const pos& h)const{return y<h.y;} void calc(){ add(x,w); } }e[M]; void $(LL &x){x=lower_bound(xs,xs+xp,x)-xs+1;} int main() { LL x,y,hx,hy; n=read(); m=read(); for(int i=1;i<=n;i++){ x=read(); y=read(); hx=read(); e[ep++]=(pos){xs[xp++]=x,y,hx}; } for(int i=1;i<=m;i++){ x=read(); y=read(); hx=read(); hy=read(); xs[xp++]=x; xs[xp++]=hx; q[qp++]=(Q){x,hx,y-1,i,-1}; q[qp++]=(Q){x,hx,hy,i,1}; } sort(xs,xs+xp); for(int i=0;i<ep;i++) $(e[i].x); for(int i=0;i<qp;i++) $(q[i].l),$(q[i].r); sort(e,e+ep); sort(q,q+qp); for(int i=0,j=0;i<qp;i++){ while(j<ep&&e[j].y<=q[i].h) e[j++].calc(); q[i].calc(); } for(int i=1;i<=m;i++) printf("%lld ",ans[i]); return 0; }