• COGS 577 蝗灾


    题目描述

    C 国国土辽阔,地大物博,但是最近却在闹蝗灾……

    我们可以把 C 国国土当成一个 W×WW×W 的矩阵,你会收到一些诸如 (X,Y,Z)(X,Y,Z) 的信息,代表 (X,Y)(X,Y) 这个点增多了 ZZ 只蝗虫,而由于 C 国政府机关比较臃肿,为了批复消灭蝗虫的请求需要询问一大堆的问题,每个询问形如 (X1,Y1,X2,Y2)(X1,Y1,X2,Y2),询问在 (X1,Y1,X2,Y2)(X1,Y1,X2,Y2) 范围内有多少蝗虫(请注意询问不会改变区域内的蝗虫数)。

    你作为一个 C 国的程序员,需要编一个程序快速的回答所有的询问。

    注意:C 国一开始没有蝗虫。

    输入

    输入的第一行包括一个整数 WW,代表 C 国国土的大小;

    第二行有一个整数 NN,表示事件数;

    接下来有 NN 行表示 NN 个事件,以 1 X Y Z 的形式或 X1X1 Y1Y1 X2X2 Y2Y2 的形式给出,分别代表蝗虫的增加和询问。

    输出

    对于每个询问输出一个整数表示需要的结果。

    样例输入

    5
    8
    2 4 1 4 2
    1 3 1 8
    1 4 4 4
    2 1 3 4 4
    1 1 5 1
    1 4 4 5
    2 2 2 5 4
    2 3 2 4 4

    样例输出

    0
    4
    9
    9

    提示

    10%10% 的数据满足 W,N100W,N≤100;

    30%30% 的数据满足 W2×103,N5×103W≤2×103,N≤5×103;

    50%50% 的数据满足 W105,N5×104W≤105,N≤5×104;

    100%100% 的数据满足 W5×105,N2×105W≤5×105,N≤2×105,每次蝗虫增加数不超过 103103。


     啊我太弱了,还要看题解。。。多练练cdq分治233

    所以说,cdq的核心思想就是分块,拆开,这样就只需要考虑合并问题时多出来需要考虑的问题就好了,而这些问题往往都比原问题简单

    这道题首先把操作和询问按时间顺序放在一起

    这样从中间分开的话,多出来的问题就是,左边的修改对右边的询问造成的影响

    因为首先合并的时候左边询问不受任何影响是显然的吧?之后的修改影响不了询问

    而右边的询问既需要右边的一些修改,也会需要左边的修改

    而这样的话就发现修改与询问之间的先后顺序被解决了

    用扫描线的方式按x排序用树状数组处理

    x从小到大扫过去

    对于一个修改,就在这个y位置上加z

    遇到一个矩形左边,就在答案上减去这个区间的和

    遇到一个矩形右边,就在答案上加上这个区间的和

    具体细节看代码吧~(ง •_•)ง

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define maxn 200005
     4 #define maxw 500005
     5 using namespace std;
     6 int w,n,cnt;
     7 struct event{
     8     int opt,x1,y1,x2,y2,z,id;
     9 }A[maxn],B[maxn];
    10 bool cmp(event A,event B){return (A.x1!=B.x1)?(A.x1<B.x1):(A.opt<B.opt);}
    11 int ans[maxn],c[maxw];
    12 void add(int x,int z){while(x<=w+1){c[x]+=z;x+=(x&(-x));}}
    13 int sum(int x){int ans=0;while(x>=1){ans+=c[x];x-=(x&(-x));}return ans;}
    14 int query(int l,int r){return sum(r)-sum(l-1);}
    15 void solve(int l,int r){
    16     if(l==r)return;
    17     int mid=(l+r)/2;
    18     solve(l,mid);solve(mid+1,r);
    19     int d=0;
    20     for(int i=l;i<=mid;i++)
    21         if(A[i].opt==1)
    22             B[d++]=A[i];
    23     for(int i=mid+1;i<=r;i++)
    24         if(A[i].opt==2){
    25             B[d]=A[i];B[d].x1--;d++;
    26             B[d]=A[i];B[d].opt=3;B[d].x1=B[d].x2;d++;
    27         }
    28     sort(B,B+d,cmp);
    29     for(int i=0;i<d;i++){
    30         if(B[i].opt==1)add(B[i].y1,B[i].z);
    31         else if(B[i].opt==2)ans[B[i].id]-=query(B[i].y1,B[i].y2);
    32         else ans[B[i].id]+=query(B[i].y1,B[i].y2);
    33     }
    34     for(int i=0;i<d;i++)if(B[i].opt==1)add(B[i].y1,-B[i].z);
    35 }
    36 int main(){
    37     scanf("%d%d",&w,&n);
    38     for(int i=1;i<=n;i++){
    39         scanf("%d%d%d",&A[i].opt,&A[i].x1,&A[i].y1);A[i].y1++;
    40         if(A[i].opt==1)scanf("%d",&A[i].z);
    41         else scanf("%d%d",&A[i].x2,&A[i].y2),A[i].y2++;
    42         A[i].id=i;
    43     }
    44     solve(1,n);
    45     for(int i=1;i<=n;i++)
    46     if(A[i].opt==2)
    47     printf("%d
    ",ans[A[i].id]);
    48     return 0;
    49 }
    View Code
  • 相关阅读:
    Static Fields and Methods
    usermod
    理解Java的Class类、"this."关键字、Constructor构造器(一)
    [REPRINT] Java 101: Classes and objects in Java
    第六章 Java并发容器和框架
    第五章 Java中锁
    第四章 Java并发编程基础
    第三章 Java内存模型(下)
    第三章 Java内存模型(上)
    第二章 并发机制的底层实现原理
  • 原文地址:https://www.cnblogs.com/2017SSY/p/10198821.html
Copyright © 2020-2023  润新知