• Tyvj1474 打鼹鼠


    Description

    在这个“打鼹鼠”的游戏中,鼹鼠会不时地从洞中钻出来,不过不会从洞口钻进去(鼹鼠真胆大……)。洞口都在
    一个大小为n(n<=1024)的正方形中。这个正方形在一个平面直角坐标系中,左下角为(0,0),右上角为(n-1,n-1)。
    洞口所在的位置都是整点,就是横纵坐标都为整数的点。而SuperBrother也不时地会想知道某一个范围的鼹鼠总数
    。这就是你的任务。

    Input

    每个输入文件有多行。
    第一行,一个数n,表示鼹鼠的范围。
    以后每一行开头都有一个数m,表示不同的操作:
    m=1,那么后面跟着3个数x,y,k(0<=x,y<n),表示在点(x,y)处新出现了k只鼹鼠;
    m=2,那么后面跟着4个数x1,y1,x2,y2(0<=x1<=x2<n,0<=y1<=y2<n),表示询问矩形(x1,y1)-(x2,y2)内的鼹鼠数量;
    m=3,表示老师来了,不能玩了。保证这个数会在输入的最后一行。
    询问数不会超过10000,鼹鼠数不会超过maxlongint。

    Output

    对于每个m=2,输出一行数,这行数只有一个数,即所询问的区域内鼹鼠的个数。

    Sample Input

    4
    1 2 2 5
    2 0 0 2 3
    3
    

    Sample Output

    5

    乍一看这个题目,是不是很像线段树操作,欸,这个二维平面怎么线段树啊

    让我们来想一想,一颗线段树维护x轴,另一颗维护y轴,

    那线段树岂不是要嵌套,那外层的线段树的每一个节点都代表1个x坐标,那么每个节点都得保存一颗线段树,那颗内层的线段树就保存y坐标;

    这种数据结构就叫做二维线段树

    修改操作就稍微麻烦一点了

    要先在外层线段树中查找x坐标,再到当前x坐标保存的y坐标的线段树中去找,进行修改



    提示:外层线段树是不能进行修改的!!!

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 using namespace std;
     5 int a,b,c,d,n,m,ans;
     6 void read(int &x) {
     7     char ch; bool ok;
     8     for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
     9     for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
    10 }
    11 struct oo
    12 {
    13     int a,b;
    14     struct o{int a,b,num;}y[3025];
    15     void build(int now,int l,int r)
    16     {
    17         y[now].a=l,y[now].b=r;
    18         if(l==r)return ;
    19         build(now<<1,l,l+r>>1);
    20         build(now<<1|1,(l+r>>1)+1,r);
    21     }
    22     void change(int now,int r,int num)
    23     {
    24         y[now].num+=num;
    25         if(y[now].a==y[now].b)return ;
    26         int mid=y[now].a+y[now].b>>1;
    27         if(r<=mid)change(now<<1,r,num);
    28         else change(now<<1|1,r,num);
    29     }
    30     void get(int now,int b1,int b2)
    31     {
    32         if(b1<=y[now].a&&b2>=y[now].b)
    33             ans+=y[now].num;
    34         else
    35         {
    36             int mid=y[now].a+y[now].b>>1;
    37             if(b1<=mid)get(now<<1,b1,b2);
    38             if(b2>mid)get(now<<1|1,b1,b2);
    39         }
    40 }
    41 }x[3025];
    42 void build(int now,int l,int r)
    43 {
    44     x[now].a=l,x[now].b=r;
    45     x[now].build(1,0,n);
    46     if(l==r)return ;
    47     build(now<<1,l,l+r>>1);
    48     build(now<<1|1,(l+r>>1)+1,r);
    49 }
    50 void change(int now,int l,int r,int num)
    51 {
    52     x[now].change(1,r,num);
    53     if(x[now].a==x[now].b)return ;
    54     int mid=x[now].a+x[now].b>>1;
    55     if(l<=mid)change(now<<1,l,r,num);
    56     else change(now<<1|1,l,r,num);
    57 }
    58 void get(int now,int a1,int a2,int b1,int b2)
    59 {
    60     if(a1<=x[now].a&&a2>=x[now].b)
    61         x[now].get(1,b1,b2);
    62     else
    63     {
    64         int mid=x[now].a+x[now].b>>1;
    65         if(a1<=mid)get(now<<1,a1,a2,b1,b2);
    66         if(a2>mid)get(now<<1|1,a1,a2,b1,b2);
    67     }
    68 }
    69 int main()
    70 {
    71     read(n);
    72     build(1,0,n);
    73     while(1)
    74     {   
    75         read(m);
    76         if(m==3)return 0;
    77         if(m==1)
    78         {
    79             read(a),read(b),read(c);
    80             change(1,a,b,c);
    81         }
    82         if(m==2)
    83         {
    84             read(a),read(b),read(c);read(d);
    85             get(1,a,c,b,d);
    86             printf("%d
    ",ans);
    87             ans=0;
    88         }
    89     }
    90 }
  • 相关阅读:
    第十一周作业
    第十周作业
    第九周作业
    第六周&java实验报告四
    第五周课程总结&试验报告(三)
    第四周课程总结&试验报告(二)
    第二周学习总结
    第三周课程总结&实验报告一
    2019年春第四次课程设计报告
    2019年春第三次课程设计实验报告
  • 原文地址:https://www.cnblogs.com/lcxer/p/9441542.html
Copyright © 2020-2023  润新知