zoukankan      html  css  js  c++  java
  • COGS1752. [BOI2007]摩基亚Mokia(CDQ,树状数组)

    题目描述

    摩尔瓦多的移动电话公司摩基亚(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个。

    题解

    树状数组没有清空结果调了几个小时……快疯了……

    坐标范围太大,先考虑离散

    我们把一个操作看成$(a,x,y)$的形式,其中$a$代表时间,$x,y$代表坐标(查询操作可以通过差分拆成四个操作)

    然后就是一个三维偏序问题了,用CDQ+树状数组解决

    时间这一维是默认有序的

    $x$这一维可以用CDQ自带的归并排好序

    $y$这一维用树状数组就可以求出答案

     1 //minamoto
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     6 char buf[1<<21],*p1=buf,*p2=buf;
     7 inline int read(){
     8     #define num ch-'0'
     9     char ch;bool flag=0;int res;
    10     while(!isdigit(ch=getc()))
    11     (ch=='-')&&(flag=true);
    12     for(res=num;isdigit(ch=getc());res=res*10+num);
    13     (flag)&&(res=-res);
    14     #undef num
    15     return res;
    16 }
    17 char sr[1<<21],z[20];int C=-1,Z;
    18 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    19 inline void print(int x){
    20     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
    21     while(z[++Z]=x%10+48,x/=10);
    22     while(sr[++C]=z[Z],--Z);sr[++C]='
    ';
    23 }
    24 const int N=200005;
    25 struct node{
    26     int x,y,d,id;
    27     inline void add(int a,int b,int c,int _id=0)
    28     {x=a,y=b,d=c,id=_id;}
    29     inline bool operator <(const node &b)const{
    30         return x!=b.x?x<b.x:
    31         y!=b.y?y<b.y:
    32         d>b.d;
    33     }
    34 }a[N],p[N];int n,m,ans[N];
    35 int c[N*10];
    36 inline void add(int x,int val){
    37     for(int i=x;i<=n;i+=i&(-i))
    38     c[i]+=val;
    39 }
    40 inline int query(int x){
    41     int res=0;
    42     for(int i=x;i;i-=i&(-i))
    43     res+=c[i];
    44     return res;
    45 }
    46 inline void clear(int x){
    47     for(int i=x;i<=n;i+=i&(-i))
    48     if(c[i]) c[i]=0;
    49     else return;
    50 }
    51 void cdq(int l,int r){
    52     if(l==r) return;
    53     int mid=(l+r)>>1;
    54     cdq(l,mid),cdq(mid+1,r);
    55     int i=l,j=l,k=mid+1;
    56     while(j<=mid&&k<=r){
    57         if(p[j]<p[k]){
    58             if(p[j].d) add(p[j].y,p[j].d);
    59             a[i++]=p[j++];
    60         }
    61         else{
    62             if(!p[k].d) ans[p[k].id]+=query(p[k].y);
    63             a[i++]=p[k++];
    64         }
    65     }
    66     while(j<=mid) a[i++]=p[j++];
    67     while(k<=r){
    68         if(!p[k].d) ans[p[k].id]+=query(p[k].y);
    69         a[i++]=p[k++];
    70     }
    71     for(int i=l;i<=r;++i){
    72         clear(a[i].y);p[i]=a[i];
    73     }
    74 }
    75 int main(){
    76     //freopen("testdata.in","r",stdin);
    77     n=read(),n=read();
    78     for(int x,y,xx,yy,opt;(opt=read())!=3;){
    79         x=read(),y=read(),xx=read();
    80         if(opt&1){
    81             p[++m].add(x,y,xx,m+1);
    82             ans[m]=-1;
    83         }
    84         else{
    85             yy=read();
    86             p[++m].add(xx,yy,0,m+1),p[++m].add(x-1,yy,0,m+1);
    87             p[++m].add(xx,y-1,0,m+1),p[++m].add(x-1,y-1,0,m+1);
    88         }
    89     }
    90     cdq(1,m);
    91     for(int i=1;i<=m;++i)
    92     if(~ans[i]){
    93         int k=ans[i]-ans[i+1]-ans[i+2]+ans[i+3];
    94         print(k);i+=3;
    95     }
    96     Ot();
    97     return 0;
    98 }
  • 相关阅读:
    problems_jenkins
    JAVA异常处理之finally中最好不要使用return
    IntelliJ idea学习资源
    Mybatis 的分页条件查询语句编写
    maven相关的学习资料
    git相关的学习资料
    开端三(1)
    开端2(2)
    C# 排序小测试
    想为一个类定义[][]方法
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9454692.html
Copyright © 2011-2022 走看看