zoukankan      html  css  js  c++  java
  • 【BOI2007】摩基亚Mokia

    P1948 - 【BOI2007】摩基亚Mokia

    Description

    摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统。和其他的定位系统一样,它能够迅速回答任何形如“用户C的位置在哪?”的问题,精确到毫米。但其真正高科技之处在于,它能够回答形如“给定区域内有多少名用户?”的问题。
    在定位系统中,世界被认为是一个W * W的正方形区域,由1 * 1的方格组成。每个方格都有一个坐标(x,y),1<=x,y<=W。坐标的编号从1开始。对于一个4 * 4的正方形,就有1<=x<=4,1<=y<=4(如图):

    P

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

    Input

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

    Output

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

    Sample Input

    0 4
    1 2 3 3
    2 1 1 3 3
    1 2 2 2
    2 2 2 3 4
    3

    Sample Output

    3
    5

    Hint

    样例提示:
    输入             输出         意义
    0 4                             大小为4 * 4的全零正方形
    1 2 3 3                         向(2,3)方格加入3名用户
    2 1 1 3 3                     查询矩形1<=x<=3,1<=y<=3内的用户数量
                        3                查询结果
    1 2 2 2                         向(2,2)方格加入2名用户
    2 2 2 3 4                     查询矩形2<=x<=3,2<=y<=4内的用户数量
                        5                 查询结果
    3                                 终止程序

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

    离线处理每个询问,把一个查询操作分解成四个二维前缀和。每个询问维护一个询问时间,一个x坐标,一个y坐标。
    Q为增加,P为查询,只有当Qx<=Px&& Qy<=Py && Qt<=Pt 时才能对P产生贡献,然后就可以用CDQ分治维护三维偏序。
    第一维时间直接排序,第二维xCDQ分治,只要计算左区间的增加对右区间的查询的影响,第三维y插入树状数组。
     1 #include<set>
     2 #include<map>
     3 #include<queue>
     4 #include<stack>
     5 #include<ctime>
     6 #include<cmath>
     7 #include<string>
     8 #include<vector>
     9 #include<cstdio>
    10 #include<cstdlib>
    11 #include<cstring>
    12 #include<iostream>
    13 #include<algorithm>
    14 #define maxn 2000100
    15 using namespace std;
    16 struct data{
    17   int t,x,y,da,id;
    18   int an,po;
    19 }e[maxn];
    20 int LOL=0,co[maxn],tree[maxn],ans[maxn];
    21 int lowbit(int x){return x&-x;}
    22 bool cmpcdq(const data &a,const data &b){
    23   if(a.x!=b.x) return a.x<b.x;
    24   else return a.y<b.y;
    25 }
    26 void add(int p,int w){
    27   for(int i=p;i<=maxn;i+=lowbit(i)){
    28     if(co[i]!=LOL) tree[i]=0;
    29     co[i]=LOL;
    30     tree[i]+=w;
    31   }
    32 }
    33 int find(int p){
    34   if(p==0) return 0;
    35   int sum=0;
    36   for(int i=p;i;i-=lowbit(i))
    37     if(co[i]==LOL)
    38       sum+=tree[i];
    39   return sum;
    40 }
    41 void CDQ(int l,int r){
    42   if(l==r) return;
    43   int mid=(l+r)>>1;
    44   CDQ(l,mid),CDQ(mid+1,r);
    45   sort(e+l,e+mid+1,cmpcdq);sort(e+mid+1,e+r+1,cmpcdq);
    46   LOL++;
    47   for(int j=mid+1,i=l;j<=r;j++){
    48     for(;i<=mid && e[i].x<=e[j].x;i++)
    49       if(e[i].id==1)
    50     add(e[i].y,e[i].da);
    51     if(e[j].id==2)
    52       e[j].an+=find(e[j].y);
    53   }
    54 }
    55 int main()
    56 {
    57   freopen("!.in","r",stdin);
    58   freopen("!.out","w",stdout);
    59   int n,type,t=0,tot=0,ans1=0;
    60   scanf("%d",&n),scanf("%d",&n);
    61   while(1){
    62     scanf("%d",&type);if(type==3) break;
    63     t++;tot++;
    64     if(type==1)scanf("%d%d%d",&e[tot].x,&e[tot].y,&e[tot].da),e[tot].id=1,e[tot].t=t;
    65     else{
    66       int x,y,xx,yy;
    67       ++ans1;
    68       scanf("%d%d%d%d",&x,&y,&xx,&yy);
    69       e[tot].x=xx,e[tot].y=yy,e[tot].id=2,e[tot].da=1,e[tot].t=t,e[tot].po=ans1;tot++;
    70       e[tot].x=xx,e[tot].y=y-1,e[tot].id=2,e[tot].da=2,e[tot].t=t,e[tot].po=ans1;tot++;
    71       e[tot].x=x-1,e[tot].y=yy,e[tot].id=2,e[tot].da=3,e[tot].t=t,e[tot].po=ans1;tot++;
    72       e[tot].x=x-1,e[tot].y=y-1,e[tot].id=2,e[tot].da=4,e[tot].t=t;e[tot].po=ans1;
    73     }
    74   }
    75   
    76   CDQ(1,tot);
    77   for(int i=1;i<=tot;i++)
    78     if(e[i].id==2){
    79       if(e[i].da==1 || e[i].da==4)
    80     ans[e[i].po]+=e[i].an;
    81       else
    82     ans[e[i].po]-=e[i].an;
    83     }
    84   for(int i=1;i<=ans1;i++)
    85     printf("%d
    ",ans[i]);
    86   return 0;
    87 }
  • 相关阅读:
    ORA-28000 帐户已被锁定问题处理
    德邦总管 修改oracle数据库用户密码的方法
    测试面试题目
    python 把一文件包含中文的字符写到另外文件乱码 UnicodeDecodeError: 'gbk' codec can't decode byte 0xac in position
    python version 2.7 required,which was not found in the registry
    ImportError: No module named dateutil.parser
    解决python2.x用urllib2证书验证错误, _create_unverified_context
    python多版本兼容性问题:当同时安装Python2和Python3后,如何兼容并切换
    MAC OS git客户端安装及操作
    Pycharm连接gitlab
  • 原文地址:https://www.cnblogs.com/pantakill/p/6657794.html
Copyright © 2011-2022 走看看