首页 > 代码库 > bzoj4822: [Cqoi2017]老C的任务

bzoj4822: [Cqoi2017]老C的任务

4822: [Cqoi2017]老C的任务

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 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

Sample Output

11
4
——————————————————————
这道题明显的扫描线QAQ 数据范围没给就开大了点
横纵坐标 x y 离散化x 按 排序 然后按 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\n",ans[i]);
    return 0;
}
View Code

bzoj4822: [Cqoi2017]老C的任务