重庆OI2017 老 C 的任务
老 C 的任务
时间限制: 2 Sec 内存限制: 512 MB题目描述
老 C 是个程序员。
最近老 C 从老板那里接到了一个任务——给城市中的手机基站写个管理系统。作为经验丰富的程序员,老 C 轻松地完成了系统的大部分功能,并把其中一个功能交给你来实现。
由于一个基站的面积相对于整个城市面积来说非常的小,因此每个的基站都可以看作坐标系中的一个点,其位置可以用坐标(x,y)来表示。此外,每个基站还有很多属性,例如高度、功率等。运营商经常会划定一个区域,并查询区域中所有基站的信息。
现在你需要实现的功能就是,对于一个给定的矩形区域,回答该区域中(包括区域边界上的)所有基站的功率总和。如果区域中没有任何基站,则回答 0。
最近老 C 从老板那里接到了一个任务——给城市中的手机基站写个管理系统。作为经验丰富的程序员,老 C 轻松地完成了系统的大部分功能,并把其中一个功能交给你来实现。
由于一个基站的面积相对于整个城市面积来说非常的小,因此每个的基站都可以看作坐标系中的一个点,其位置可以用坐标(x,y)来表示。此外,每个基站还有很多属性,例如高度、功率等。运营商经常会划定一个区域,并查询区域中所有基站的信息。
现在你需要实现的功能就是,对于一个给定的矩形区域,回答该区域中(包括区域边界上的)所有基站的功率总和。如果区域中没有任何基站,则回答 0。
输入
第一行两个整数n, m ,表示一共有n个基站和m 次查询。
接下来一共有n行,每行由xB,yB,pB三个空格隔开的整数构成,表示一个基站的坐标(xB,yB)和功率pB。不会有两个基站位于同一坐标。
接下来一共有m行,每行由x1E,y1E,x2E,y2E四个空格隔开的整数构成,表示一次查询的矩形区域。该矩形对角坐标为(x1E,y1E)和(x2E,y2E),且 4 边与坐标轴平行。
接下来一共有n行,每行由xB,yB,pB三个空格隔开的整数构成,表示一个基站的坐标(xB,yB)和功率pB。不会有两个基站位于同一坐标。
接下来一共有m行,每行由x1E,y1E,x2E,y2E四个空格隔开的整数构成,表示一次查询的矩形区域。该矩形对角坐标为(x1E,y1E)和(x2E,y2E),且 4 边与坐标轴平行。
输出
输出m行,每行一个整数,对应每次查询的结果。
样例输入
4 2
0 0 1
0 1 2
2 2 4
1 0 8
0 0 1 1
1 1 5 6
样例输出
11
4
提示
1≤n≤100000,1≤m≤100000。-231≤xi,yi,pi,x1j,y1j,x2j,y2j<231,x1j≤x2j,y1j≤y2j
分析:求矩形面积,离线扫描线,树状数组或线段树维护前缀和即可;
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <bitset> #include <map> #include <queue> #include <stack> #include <vector> #include <cassert> #include <ctime> #define rep(i,m,n) for(i=m;i<=(int)n;i++) #define mod 1000000007 #define inf 0x3f3f3f3f #define vi vector<int> #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) #define pii pair<int,int> #define sys system("pause") #define ls rt<<1 #define rs rt<<1|1 #define all(x) x.begin(),x.end() const int maxn=3e5+10; const int N=5e2+10; using namespace std; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qpow(ll p,ll q,ll mo){ll f=1;while(q){if(q&1)f=f*p%mo;p=p*p%mo;q>>=1;}return f;} int n,m,k,t,x[maxn<<2],y[maxn<<2]; ll sum[maxn<<2],ret[maxn]; struct node { int x,y,z; }a[maxn]; struct query { node l,r; }q[maxn]; vi qu[maxn]; vector<pii>pos[maxn]; void pup(int rt) { sum[rt]=sum[ls]+sum[rs]; } void upd(int L,ll v,int l,int r,int rt) { if(l==r) { sum[rt]+=v; return; } int mid=l+r>>1; if(L<=mid)upd(L,v,l,mid,ls); else upd(L,v,mid+1,r,rs); pup(rt); } ll gao(int L,int R,int l,int r,int rt) { if(L==l&&R==r) { return sum[rt]; } int mid=l+r>>1; if(R<=mid)return gao(L,R,l,mid,ls); else if(L>mid)return gao(L,R,mid+1,r,rs); else return gao(L,mid,l,mid,ls)+gao(mid+1,R,mid+1,r,rs); } int main() { int i,j; scanf("%d%d",&n,&m); rep(i,1,n) { scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z); x[++x[0]]=a[i].x,y[++y[0]]=a[i].y; } rep(i,1,m) { scanf("%d%d%d%d",&q[i].l.x,&q[i].l.y,&q[i].r.x,&q[i].r.y); x[++x[0]]=q[i].l.x,x[++x[0]]=q[i].r.x; y[++y[0]]=q[i].l.y,y[++y[0]]=q[i].r.y; } sort(x+1,x+x[0]+1); x[0]=unique(x+1,x+x[0]+1)-x-1; sort(y+1,y+y[0]+1); y[0]=unique(y+1,y+y[0]+1)-y-1; rep(i,1,n) { a[i].x=lower_bound(x+1,x+x[0]+1,a[i].x)-x; a[i].y=lower_bound(y+1,y+y[0]+1,a[i].y)-y; pos[a[i].x].pb(mp(a[i].y,a[i].z)); } rep(i,1,m) { q[i].l.x=lower_bound(x+1,x+x[0]+1,q[i].l.x)-x; q[i].l.y=lower_bound(y+1,y+y[0]+1,q[i].l.y)-y; q[i].r.x=lower_bound(x+1,x+x[0]+1,q[i].r.x)-x; q[i].r.y=lower_bound(y+1,y+y[0]+1,q[i].r.y)-y; qu[q[i].l.x-1].pb(i); qu[q[i].r.x].pb(i); } rep(i,1,x[0]) { rep(j,0,pos[i].size()-1)upd(pos[i][j].fi,pos[i][j].se,1,y[0],1); rep(j,0,qu[i].size()-1) { if(i==q[qu[i][j]].l.x-1)ret[qu[i][j]]-=gao(q[qu[i][j]].l.y,q[qu[i][j]].r.y,1,y[0],1); else ret[qu[i][j]]+=gao(q[qu[i][j]].l.y,q[qu[i][j]].r.y,1,y[0],1); } } rep(i,1,m)printf("%lld\n",ret[i]); return 0; }