hdu1823二维线段树,单点跟新,区间求最大值。

/*
思路:以身高为x,活泼度为y建立二维线段树,然后其余就是二维线段树的区间最值和单点跟新.
然后有 升高和活泼度相同,但是缘分不同的数据。
还有输入查询数据的时候 有可能 区间大的输入在区间小的的前面
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <algorithm>
using namespace std;
int m;
int sum[102*4+10][1002*4+10];
int n=1000;
int mx;
int max(int x,int y)
{
    if(x<y) return y;
    return x;
}
void pushup(int rt,int xrt)
{
    sum[xrt][rt]=max(sum[xrt][rt*2],sum[xrt][rt*2+1]);
}
void buildy(int rt,int left,int right,int xrt)
{
    sum[xrt][rt] = -1;
    if(left != right){
        int mid=(left+right)/2;
        buildy(rt*2,left,mid,xrt);
        buildy(rt*2+1,mid+1,right,xrt);
    }

}
void build(int rt,int left,int right)
{
    buildy(1,0,n,rt);
    if(left!=right)
    {
        int mid=(left+right)/2;
        build(rt*2,left,mid);
        build(rt*2+1,mid+1,right);
    }
}
void updatey(int rt,int left,int right,int y,int add,int xrt)
{
    if(left==right&&left==y)
    {
        sum[xrt][rt]=max(sum[xrt][rt],add);
        return ;
    }
    int mid=(left+right)/2;
    if(y<=mid) updatey(rt*2,left,mid,y,add,xrt);
    if(y>mid) updatey(rt*2+1,mid+1,right,y,add,xrt);
    pushup(rt,xrt);
}
void update(int rt,int left,int right,int x,int y,int add)
{   // printf("%d %d %d\n",rt,left,right);
     updatey(1,0,n,y,add,rt);
     if(left!=right)
     {
         int mid=(left+right)/2;
         if(x<=mid) update(rt*2,left,mid,x,y,add);
         if(x>mid)  update(rt*2+1,mid+1,right,x,y,add);
     }
}
void queryY(int rt,int left,int right,int y1,int y2,int xrt)
{
    if(left>=y1&&right<=y2)
    {
        mx=max(mx,sum[xrt][rt]);
        return ;
    }
    int mid=(right+left)/2;
    if(y1<=mid) queryY(rt*2,left,mid,y1,y2,xrt);
    if(y2>mid) queryY(rt*2+1,mid+1,right,y1,y2,xrt);
}
void query(int rt,int left,int right,int x1,int y1,int x2,int y2)
{
    if(left>=x1&&right<=x2)
    {
        queryY(1,0,n,y1,y2,rt);
        return ;
    }
    int mid=(left+right)/2;
    if(x1<=mid) query(rt*2,left,mid,x1,y1,x2,y2);
    if(x2>mid) query(rt*2+1,mid+1,right,x1,y1,x2,y2);
}
int main()
{  char a[5];
   int h,h2;
   double y,y2,num;
   while(scanf("%d",&m)&&m)
   {   build(1,100,200);
       while(m--)
       {
           scanf("%s",a);
           if(a[0]=='I')
           {
            scanf("%d %lf %lf",&h,&y,&num);
            y=y*10,num=num*10;
          //  printf("%d %f,%f\n",h,y,num);
            update(1,100,200,h,(int)y,(int)num);
           }
           else
           {
               mx=-1;
               scanf("%d %d %lf %lf",&h,&h2,&y,&y2);
               y=y*10,y2=y2*10;
                if(h > h2) {int t=h;h=h2,h2=t;}
                if(y > y2) {double t=y;y=y2,y2=t;}
                query(1,100,200,h,(int)y,h2,(int)y2);
                if(mx==-1) printf("-1\n");
                else printf("%.1lf\n",mx*1.0/10);
           }
       }
   }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值