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 }
  • 相关阅读:
    C# 不用添加WebService引用,调用WebService方法
    贪心 & 动态规划
    trie树 讲解 (转载)
    poj 2151 Check the difficulty of problems (检查问题的难度)
    poj 2513 Colored Sticks 彩色棒
    poj1442 Black Box 栈和优先队列
    啦啦啦
    poj 1265 Area(pick定理)
    poj 2418 Hardwood Species (trie树)
    poj 1836 Alignment 排队
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9454692.html
Copyright © 2011-2022 走看看