• BZOJ4822[Cqoi2017]老C的任务——树状数组(二维数点)


    题目描述

    老 C 是个程序员。    
    最近老 C 从老板那里接到了一个任务——给城市中的手机基站写个管理系统。作为经验丰富的程序员,老 C 轻松
    地完成了系统的大部分功能,并把其中一个功能交给你来实现。由于一个基站的面积相对于整个城市面积来说非常
    的小,因此每个的基站都可以看作坐标系中的一个点,其位置可以用坐标(x, y)来表示。此外,每个基站还有很多属
    性,例如高度、功率等。运营商经常会划定一个区域,并查询区域中所有基站的信息。现在你需要实现的功能就是,
    对于一个给定的矩形区域,回答该区域中(包括区域边界上的)所有基站的功率总和。如果区域中没有任何基站,则回
    答 0。

    输入

    第一行两个整数 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。   

    输出

    输出 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
     
      经典的二维数点问题,离线询问,将给出的点和询问的点一起排序,按排序后顺序操作,询问就直接树状数组上查询,插入点在树状数组对应位置加上就好了。但注意要离散化并且开longlong。
    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    using namespace std;
    struct node
    {
        int x;
        int y;
        int num;
        int cnt;
        int v;
    }s[10000010];
    int n,m;
    ll v[10000010];
    int a,b,c,d;
    int g[10000010];
    int maxy;
    int tot;
    ll ans[2000010][5];
    void add(int x,int k)
    {
        for(int i=x;i<=maxy;i+=i&-i)
        {
            v[i]+=1ll*k;
        }
    }
    ll ask(int x)
    {
        ll res=0;
        for(int i=x;i;i-=i&-i)
        {
            res+=v[i];
        }
        return res;
    }
    bool cmp(node a,node b)
    {
        if(a.x==b.x)
        {
            if(a.y==b.y)
            {
                return a.cnt<b.cnt; 
            }
            return a.y<b.y;
        }
        return a.x<b.x;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)   
        {
            scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].v);
            g[i]=s[i].y;
        }
        tot=n;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d%d",&a,&b,&c,&d);
            s[++tot].x=a-1;
            s[tot].y=b-1;
            s[tot].cnt=i;
            s[tot].num=1;
            g[tot]=b-1;
            s[++tot].x=a-1;
            s[tot].y=d;
            s[tot].cnt=i;
            s[tot].num=2;
            g[tot]=d;
            s[++tot].x=c;
            s[tot].y=b-1;
            s[tot].cnt=i;
            s[tot].num=3;
            g[tot]=b-1;
            s[++tot].x=c;
            s[tot].y=d;
            s[tot].cnt=i;
            s[tot].num=4;
            g[tot]=d;
        }
        sort(g+1,g+1+tot);
        sort(s+1,s+1+tot,cmp);
        maxy=unique(g+1,g+1+tot)-g-1;
        for(int i=1;i<=tot;i++)
        {
            if(!s[i].cnt)
            {
                int val=lower_bound(g+1,g+1+maxy,s[i].y)-g;
                add(val,s[i].v);
            }
            else
            {
                int val=lower_bound(g+1,g+1+maxy,s[i].y)-g;
                ans[s[i].cnt][s[i].num]=ask(val);
            }
        }
        for(int i=1;i<=m;i++)
        {
            printf("%lld
    ",ans[i][4]+ans[i][1]-ans[i][2]-ans[i][3]);
        }
    }
  • 相关阅读:
    Brettle.Web.NeatUpload.dll支持的大文件上传
    流媒体服务器架设(转载)
    Photoshop用户必知必会的28个快捷键
    qq服务器Ip
    环球企业家:web2.0创业时代将终结
    真传丹道小周天功.txt
    如何解决管理工具MSC拒绝访问?
    photoshop快捷键大全
    利用ffmpeg把视频文件转换为flv文件
    编写高性能 Web 应用程序的 10 个技巧 转自微软资料
  • 原文地址:https://www.cnblogs.com/Khada-Jhin/p/9559088.html
Copyright © 2020-2023  润新知