二维线段树维护最大值hdu1823

本文详细介绍了一种使用二维线段树的数据结构来解决区间查询和更新问题的方法。通过具体的代码示例,讲解了如何构建二维线段树,并实现区间最大值的查询与更新操作。适用于需要高效处理二维区间问题的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:很裸地二维线段树,就是维护区间最大值

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=1010;

int M;
char op[5];
int H,H1,H2,A1,A2,A,L, ans;

struct IntervalTree
{
    int maxv[110<<3][maxn<<3];
    void build()
    {
        memset(maxv,-1,sizeof(maxv));
    }
    void updateY(int xo,int o,int l,int r,int x,int flag)
    {
        if(l==r)
        {
            if(flag!=-1){maxv[xo][o]=max(maxv[xo][o],x);}//注意如果两个女孩的身高和活跃度相同,取最大值
            else maxv[xo][o]=max(maxv[xo<<1][o],maxv[xo<<1|1][o]);
            return;
        }
        int mid=(l+r)>>1;
        if(A<=mid)updateY(xo,o<<1,l,mid,x,flag);
        else updateY(xo,o<<1|1,mid+1,r,x,flag);
        maxv[xo][o]=max(maxv[xo][o<<1],maxv[xo][o<<1|1]);
    }
    void updateX(int o,int l,int r,int x)
    {

        if(l==r)
        {
            updateY(o,1,0,1001,x,1);
            return;
        }
        int mid=(l+r)>>1;
        if(H<=mid)updateX(o<<1,l,mid,x);
        else updateX(o<<1|1,mid+1,r,x);
        updateY(o,1,0,1001,x,-1);
    }
    void queryY(int xo,int o,int l,int r)
    {
        if(A1<=l&&r<=A2)
        {
            ans=max(ans,maxv[xo][o]);
            return ;
        }
        int mid=(l+r)>>1;
        if(A1<=mid)queryY(xo,o<<1,l,mid);
        if(A2>mid)queryY(xo,o<<1|1,mid+1,r);
    }
    void queryX(int o,int l,int r)
    {
        if(H1<=l&&r<=H2)
        {
            queryY(o,1,0,1001);
            return ;
        }
        int mid=(l+r)>>1;
        if(H1<=mid)queryX(o<<1,l,mid);
        if(H2>mid)queryX(o<<1|1,mid+1,r);
    }
}tree;
int main()
{
    freopen("in.txt","r",stdin);
    while(scanf("%d",&M)!=EOF,M)
    {
        tree.build();
        while(M--)
        {
            scanf("%s",op);
            if(op[0]=='I')
            {
                double a,l;
                scanf("%d%lf%lf",&H,&a,&l);
                L=l*10;
                H-=100;
                A=a*10;
                tree.updateX(1,0,101,L);
            }
            else if(op[0]=='Q')
            {
                double a1,a2;
                scanf("%d%d%lf%lf",&H1,&H2,&a1,&a2);
                A1=int(a1*10),A2=int(a2*10);
                H1-=100,H2-=100;
                if(H1>H2)swap(H1,H2);
                if(A1>A2)swap(A1,A2);
                ans=-1;
                tree.queryX(1,0,101);
                if(ans>=0) printf("%.1lf\n",ans/10.0);
                else printf("-1\n");
            }
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值