HDU 1823 二维线段树

第一次写二维线段树,参考了别人代码,主要思路是类似于一维线段树,只不过线段二分思想变成了矩阵四分。
#include<cstdio>
#include<cstring>
int seg[8000*800],n;
int max(int a,int b)
{
    return a>b?a:b;
}
void ud(int al,int ar,int hl,int hr,int a,int h,int d,int i)
{
    if(seg[i]<d)
        seg[i]=d;
    if(al==ar&&hl==hr)
        return;
    int am=(al+ar)>>1;
    int hm=(hl+hr)>>1;
    if(a<=am&&h<=hm)
        ud(al,am,hl,hm,a,h,d,4*i+1);
    if(a<=am&&h>hm)
        ud(al,am,hm+1,hr,a,h,d,4*i+2);
    if(a>am&&h<=hm)
        ud(am+1,ar,hl,hm,a,h,d,4*i+3);
    if(a>am&&h>hm)
        ud(am+1,ar,hm+1,hr,a,h,d,4*i+4);
}
int qu(int al,int ar,int hl,int hr,int a1,int a2,int h1,int h2,int i)
{
    int t=-1;
    if(a1<=al&&ar<=a2&&h1<=hl&&hr<=h2)
        return seg[i];
    int am=(al+ar)>>1;
    int hm=(hl+hr)>>1;
    if(am>=a1&&hm>=h1)
        t=max(t,qu(al,am,hl,hm,a1,a2,h1,h2,4*i+1));
    if(am>=a1&&h2>hm)
        t=max(t,qu(al,am,hm+1,hr,a1,a2,h1,h2,4*i+2));
    if(a2>am&&hm>=h1)
        t=max(t,qu(am+1,ar,hl,hm,a1,a2,h1,h2,4*i+3));
    if(a2>am&&h2>hm)
        t=max(t,qu(am+1,ar,hm+1,hr,a1,a2,h1,h2,4*i+4));
    return t;
}
int main()
{
    while(scanf("%d",&n),n)
    {
        memset(seg,-1,sizeof(seg));
        for(int i=0;i<n;i++)
        {
            char s[2];
            scanf("%s",s);
            if(*s=='I')
            {
                int h;
                double a,f;
                scanf("%d%lf%lf",&h,&a,&f);
                ud(0,1000,100,200,int(10*a),h,int(10*f),1);
            }
            else
            {
                int h1,h2;
                double a1,a2;
                scanf("%d%d%lf%lf",&h1,&h2,&a1,&a2);
                if(h1>h2)
                {
                    int tp=h1;
                    h1=h2;
                    h2=tp;
                }
                if(a1>a2)
                {
                    double tp=a1;
                    a1=a2;
                    a2=tp;
                }
                int ans=qu(0,1000,100,200,int(10*a1),int(10*a2),h1,h2,1);
                if(ans==-1)
                    puts("-1");
                else
                    printf("%.1lf\n",(double)ans/10);
            }
        }
    }
    return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值