• HDU1823 Luck ans Love 二维线段树


    Luck and Love

     HDU - 1823 

    世界上上最远的距离不是相隔天涯海角 
    而是我在你面前 
    可你却不知道我爱你 
                    ―― 张小娴 

    前段日子,枫冰叶子给Wiskey做了个征婚启事,聘礼达到500万哦,天哪,可是天文数字了啊,不知多少MM蜂拥而至,顿时万人空巷,连扫地的大妈都来凑热闹来了。―_―||| 
    由于人数太多,Wiskey实在忙不过来,就把统计的事情全交给了枫冰叶子,自己跑回家休息去了。这可够枫冰叶子忙的了,他要处理的有两类事情,一是得接受MM的报名,二是要帮Wiskey查找符合要求的MM中缘分最高值。 

    Input本题有多个测试数据,第一个数字M,表示接下来有连续的M个操作,当M=0时处理中止。 
    接下来是一个操作符C。 
    当操作符为‘I’时,表示有一个MM报名,后面接着一个整数,H表示身高,两个浮点数,A表示活泼度,L表示缘分值。 (100<=H<=200, 0.0<=A,L<=100.0) 
    当操作符为‘Q’时,后面接着四个浮点数,H1,H2表示身高区间,A1,A2表示活泼度区间,输出符合身高和活泼度要求的MM中的缘分最高值。 (100<=H1,H2<=200, 0.0<=A1,A2<=100.0)
    所有输入的浮点数,均只有一位小数。 
    Output对于每一次询问操作,在一行里面输出缘分最高值,保留一位小数。 
    对查找不到的询问,输出-1。 
    Sample Input

    8
    I 160 50.5 60.0
    I 165 30.0 80.5
    I 166 10.0 50.0
    I 170 80.5 77.5
    Q 150 166 10.0 60.0
    Q 166 177 10.0 50.0
    I 166 40.0 99.9
    Q 166 177 10.0 50.0
    0

    Sample Output

    80.5
    50.0
    99.9

    ——————————————————————————————————————————————————————————————————————————

    处理二维表格中的数据修改和查询操作,用传说中的二维线段树。

    首先第一维为行,把行建立线段树,线段树的节点代表1个到多个行。

    然后把行线段树的每个节点对应的列建立线段树,每个节点代表在行节点控制范围内的1个到多个列。

    时间负责度为log(m)*log(n),其中m和n代表行数和列数。

    另外,还有一种写法,就是建立四叉线段树。也可以称为“矩形树”。实际上就是把矩形按照行和列的二分,分为4块区域。应该更好理解且更好写。只是据说这种写法复杂度有可能退化。

    ——————————————————————————————————————————————————————————————————————————

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int maxn=105;
      4 const int maxm=1005;
      5 struct Lie
      6 {
      7     int ll,lr;
      8     int max;
      9 };
     10 struct Hang
     11 {
     12     int l,r;
     13     Lie lie[maxm<<2]; 
     14 }hang[maxn<<2];
     15 int m,active,love,hight;
     16 char s[2];
     17 void buil(int hh,int cur,int l,int r)
     18 {
     19     hang[hh].lie[cur].ll=l;
     20     hang[hh].lie[cur].lr=r;
     21     hang[hh].lie[cur].max=-1;
     22     if(l==r)return ;
     23     int mid=(l+r)>>1;
     24     buil(hh,cur<<1,l,mid);
     25     buil(hh,cur<<1 | 1,mid+1,r);
     26 }
     27 void build(int cur,int l,int r,int ll,int lr)
     28 {
     29     hang[cur].l=l;hang[cur].r=r;
     30     buil(cur,1,ll,lr); 
     31     if(l==r)return ;
     32     int mid=(l+r)>>1;
     33     build(cur<<1,l,mid,ll,lr);
     34     build(cur<<1 | 1,mid+1,r,ll,lr);
     35 }
     36 void upda(int pre,int cur,int hh,int lh,int dat)
     37 {
     38     if(hang[pre].lie[cur].ll==hang[pre].lie[cur].lr)
     39     {
     40         hang[pre].lie[cur].max=max(hang[pre].lie[cur].max,dat);
     41         return ;
     42     }
     43     int mid=(hang[pre].lie[cur].ll+hang[pre].lie[cur].lr)>>1;
     44     if(lh<=mid)upda(pre,cur<<1,hh,lh,dat);
     45     else upda(pre,cur<<1|1,hh,lh,dat);
     46     hang[pre].lie[cur].max=max(hang[pre].lie[cur<<1].max,hang[pre].lie[cur<<1|1].max);
     47 }
     48 void update(int cur,int hh,int lh,int dat)
     49 {
     50     upda(cur,1,hh,lh,dat);
     51     if(hang[cur].l==hang[cur].r)return;
     52     int mid=(hang[cur].l+hang[cur].r)>>1;
     53     if(hh<=mid)update(cur<<1,hh,lh,dat);
     54     else update(cur<<1|1,hh,lh,dat);
     55 }
     56 float quer(int pre,int cur,int l1,int l2)
     57 {
     58     if(l1<=hang[pre].lie[cur].ll && hang[pre].lie[cur].lr<=l2)
     59     return hang[pre].lie[cur].max;
     60     int mid=(hang[pre].lie[cur].ll + hang[pre].lie[cur].lr)>>1;
     61     float ans=-1;
     62     if(l1<=mid)ans=max(ans,quer(pre,cur<<1,l1,l2));
     63     if(mid<l2)ans=max(ans,quer(pre,cur<<1|1,l1,l2));
     64     return ans;
     65 }
     66 float query(int cur,int h1,int h2,int l1,int l2)
     67 {
     68     if(h1<=hang[cur].l && hang[cur].r<=h2)return quer(cur,1,l1,l2);
     69     int mid=(hang[cur].l+hang[cur].r)>>1;
     70     float ans=-1;
     71     if(h1<=mid)ans=max(ans,query(cur<<1,h1,h2,l1,l2));
     72     if(h2>mid)ans=max(ans,query(cur<<1|1,h1,h2,l1,l2));
     73     return ans;
     74 }
     75 int main()
     76 {
     77     while(scanf("%d",&m)==1 && m)
     78     {
     79         build(1,100,200,0,1000);
     80         for(int i=0;i<m;i++)
     81         {
     82             scanf("%s",s);
     83             if(s[0]=='I')
     84             {
     85                 int h;
     86                 float act,lov;
     87                 scanf("%d%f%f",&h,&act,&lov);
     88                 active=(int)(10*act);
     89                 love=(int)(10*lov);
     90                 update(1,h,active,love);
     91             }
     92             else
     93             {
     94                 int h1,h2;
     95                 float a1,a2;
     96                 scanf("%d%d%f%f",&h1,&h2,&a1,&a2);
     97                 int aa1=(int)(a1*10);
     98                 int aa2=(int)(a2*10);
     99                 if(h1>h2)swap(h1,h2);
    100                 if(aa1>aa2)swap(aa1,aa2);
    101                 double ans=query(1,h1,h2,aa1,aa2);
    102                 if(ans<0)printf("-1
    ");
    103                 else printf("%.1f
    ",ans/10);
    104             }
    105         }
    106     }
    107     return 0;
    108 }
    View Code
  • 相关阅读:
    053(九)
    方法的重载
    方法的重写(override / overwrite)
    属性与局部变量的对比
    面向对象基础知识合集:对象的产生、对象的生命周期、内存解析
    使用二维数组打印一个 10 行杨辉三角
    数组中的常见异常: 1. 数组角标越界的异常:ArrayIndexOutOfBoundsExcetion 2. 空指针异常:NullPointerException
    快速排序
    * 数组的冒泡排序的实现
    * 二维数组的使用
  • 原文地址:https://www.cnblogs.com/gryzy/p/6941777.html
Copyright © 2020-2023  润新知