• 题解报告——Mokia


    题目描述

    摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统。和其他的定位系统一样,它能够迅速回答任何形如“用户C的位置在哪?”的问题,精确到毫米。但其真正高科技之处在于,它能够回答形如“给定区域内有多少名用户?”的问题。

    在定位系统中,世界被认为是一个W×W的正方形区域,由1×1的方格组成。每个方格都有一个坐标(x,y),1<=x,y<=W。坐标的编号从1开始。对于一个4×4的正方形,就有1<=x<=4,1<=y<=4(如图):

    请帮助Mokia公司编写一个程序来计算在某个矩形区域内有多少名用户。

    输入输出格式

    输入格式:

     

    有三种命令,意义如下:

    命令 参数 意义

    • 0 W 初始化一个全零矩阵。本命令仅开始时出现一次。
    • 1 x y A 向方格(x,y)中添加A个用户。A是正整数。
    • 2 X1 Y1 X2 Y2 查询X1<=x<=X2,Y1<=y<=Y2所规定的矩形中的用户数量
    • 3 无参数 结束程序。本命令仅结束时出现一次。

     

    输出格式:

     

    对所有命令2,输出一个一行整数,即当前询问矩形内的用户数量。

     

    输入输出样例

    输入样例#1: 
    0 4
    1 2 3 3
    2 1 1 3 3
    1 2 2 2
    2 2 2 3 4
    3
    输出样例#1: 
    3
    5
    

    说明

    对于所有数据:

    1<=W<=2000000
    1<=X1<=X2<=W
    1<=Y1<=Y2<=W
    1<=x,y<=W
    0<A<=10000
    命令1不超过160000个。
    命令2不超过10000个。


    【思路分析】

    CDQ模板题,由于网上博客看不懂,所以只有自行脑补,可能写得有点丑,有点慢。。。自行体会。。。

    【代码实现】

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define lowbit(x) x&(-x)
     4 using namespace std;
     5 const int N=2e6+5;
     6 struct sd{
     7     int kind,x,y,val,id;
     8 }que[N];
     9 int ans[N],t[N<<2],n,w,ord,cnt,cot;
    10 bool cmp(sd a,sd b)
    11 {
    12     if(a.x!=b.x) return a.x<b.x;
    13     if(a.y!=b.y) return a.y<b.y;
    14     return a.kind<b.kind;
    15 }
    16 void add(int v,int ww)
    17 {
    18     for(;v<=w;v+=lowbit(v))
    19     t[v]+=ww;
    20 }
    21 int ask(int v)
    22 {
    23     int res=0;
    24     for(;v;v-=lowbit(v))
    25     res+=t[v];
    26     return res;
    27 }
    28 void CDQ(int l,int r)
    29 {
    30     if(l==r) return;
    31     int mid=(l+r)>>1;
    32     CDQ(l,mid),CDQ(mid+1,r);
    33     sort(que+l,que+mid+1,cmp),sort(que+mid+1,que+r+1,cmp);
    34     int i=l,j=mid+1;
    35     for(;j<=r;j++)
    36     {
    37         while(que[i].x<=que[j].x&&i<=mid) 
    38         {
    39             if(!que[i].kind) add(que[i].y,que[i].val);
    40             i++;
    41         }
    42         if(que[j].kind) ans[que[j].id]+=que[j].val*ask(que[j].y);
    43     }
    44     for(j=l;j<i;j++) if(!que[j].kind) add(que[j].y,-que[j].val);
    45 }
    46 int main()
    47 {
    48     scanf("%d%d",&n,&w);
    49     while(1)
    50     {
    51         int a,b,c,d;
    52         scanf("%d",&ord);if(ord==3) break;
    53         scanf("%d%d%d",&a,&b,&c);
    54         if(ord==1) {que[++cnt]=(sd){0,a,b,c,0};}
    55         if(ord==2)
    56         {
    57             scanf("%d",&d);
    58             que[++cnt]=(sd){1,a-1,b-1,1,++cot};
    59             que[++cnt]=(sd){1,c,d,1,cot};
    60             que[++cnt]=(sd){1,a-1,d,-1,cot};
    61             que[++cnt]=(sd){1,c,b-1,-1,cot};
    62         }
    63     }
    64     CDQ(1,cnt);
    65     for(int i=1;i<=cot;i++) printf("%d
    ",ans[i]);
    66     return 0;
    67 }
  • 相关阅读:
    [C和指针]第一部分
    [Effective Java]第十章 并发
    [C程序设计语言]第五部分
    [C程序设计语言]第四部分
    git clone速度太慢解决方案
    Golang使用Redis
    删除校管理员的多余数据
    jQuery ajax同步的替换方法,使用 $.Deferred()对象
    打包并删除临时文件
    通过vjudge刷Uva的题目(解决Uva网站打开慢的问题)
  • 原文地址:https://www.cnblogs.com/genius777/p/9124398.html
Copyright © 2020-2023  润新知