hdu 1823

来源:互联网 发布:传奇物品数据库翻译 编辑:程序博客网 时间:2024/04/28 09:01

题目

二维的线段树。

把身高区域看成x轴,活跃度看成是y轴,就找所交区域内值的最大值。

把每一株线段树单独来看,很容易理解。

代码中有详细解释,代码如下:

#include<iostream>#include<cstdio>using namespace std;#define maxn 2050struct sub_Tree{    int l,r;    int val;};//子树struct Tree{    int l,r;    sub_Tree subtree[maxn<<2];}tree[maxn<<2];//母树,其中的一个元素即为子线段树void build_subTree(int l,int r,int sub_rt,int rt){    tree[rt].subtree[sub_rt].l=l;    tree[rt].subtree[sub_rt].r=r;    tree[rt].subtree[sub_rt].val=-1;    if(l==r) return ;    int m=(l+r)>>1;    build_subTree(l,m,sub_rt<<1,rt);    build_subTree(m+1,r,sub_rt<<1|1,rt);}//建立子树void buildTree(int l,int r,int ll,int rr ,int rt){    tree[rt].l=l;    tree[rt].r=r;    build_subTree(ll,rr,1,rt);    if(l==r) return ;    int m=(l+r)>>1;    buildTree(l,m,ll,rr,rt<<1);    buildTree(m+1,r,ll,rr,rt<<1|1);}//建立母树void update_subTree(int act,int lov,int sub_root,int rt){    int l,r;    l=tree[rt].subtree[sub_root].l;    r=tree[rt].subtree[sub_root].r;    if(l==r){        tree[rt].subtree[sub_root].val=max(tree[rt].subtree[sub_root].val,lov);        return ;    }    int m=(l+r)>>1;    if(act<=m) update_subTree(act,lov,sub_root<<1,rt);    else update_subTree(act,lov,sub_root<<1|1,rt);    tree[rt].subtree[sub_root].val=max(tree[rt].subtree[sub_root<<1].val,tree[rt].subtree[sub_root<<1|1].val);}//更新子线段树void update(int act,int lov,int height,int rt){    int l,r;    l=tree[rt].l;    r=tree[rt].r;    update_subTree(act,lov,1,rt);    if(l==r) return ;    int m=(l+r)>>1;    if(height<=m) update(act,lov,height,rt<<1);    else update(act,lov,height,rt<<1|1);}//更新母线段数int query_subtree(int x,int y,int sub_root,int rt){    int l,r;    l=tree[rt].subtree[sub_root].l;    r=tree[rt].subtree[sub_root].r;    if(l==x&&r==y){        return tree[rt].subtree[sub_root].val;    }    int m=(l+r)>>1;    int ret=-1;    if(x<=m) ret=max(ret,query_subtree(x,min(y,m),sub_root<<1,rt));    if(y>m) ret=max(ret,query_subtree(max(m+1,x),y,sub_root<<1|1,rt));    return ret;}//询问子树int query(int x,int y,int xx,int yy,int rt){    int l,r;    l=tree[rt].l;    r=tree[rt].r;    if(l==x&&r==y){        return query_subtree(xx,yy,1,rt);    }    int m=(l+r)>>1;    int ret=-1;    if(x<=m) ret=max(ret,query(x,min(m,y),xx,yy,rt<<1));    if(y>m) ret=max(ret,query(max(m+1,x),y,xx,yy,rt<<1|1));    return ret;}//询问母树int main(){    int n;    char op[5];    while(scanf("%d",&n),n){        buildTree(100,200,0,1000,1);        while(n--){            scanf("%s",op);            int height1,height2;            double act1,act2,lov;            if(op[0]=='I'){                scanf("%d%lf%lf",&height1,&act1,&lov);       //         cout<<(int)(act1*10)<<" "<<(int)(lov*10)<<endl;                update((int)(act1*10),(int)(lov*10),height1,1);            }            else{                scanf("%d%d%lf%lf",&height1,&height2,&act1,&act2);                if(height1>height2) swap(height1,height2);                if(act1>act2) swap(act1,act2);                double ans=query(height1,height2,(int)(act1*10),(int)(act2*10),1);                if(ans<0) puts("-1");                else printf("%.1lf\n",ans/10);            }        }    }    return 0;}