/*
这题需要用二维线段树,二维线段树就是在一维的基础上稍作改变即可
第一维是身高,第二维是活泼度(这里身高从0-100计算,活泼度0-1000计算)
然后在用maxx数组保存每第一维每个身高中每个活泼度区间的最大缘分值
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lson left, mid, root<<1, k
#define rson mid+1, right, root<<1|1, k
using namespace std;
double maxx[111][1005<<2];
void Build(int left, int right, int root, int k)//建立二维线段树
{
int mid = (left+right) >> 1;
maxx[k][root] = 0;//把每个节点的最大值初始化为0
if(left == right) return ;
Build(lson);//建立左节点
Build(rson);//建立右节点
}
void Updata(int left, int right, int root, int k, int a, double l)
{
if(left==a && right==a)//找到活泼度为a的节点,把l赋给这个节点
{
maxx[k][root] = max(maxx[k][root],l);
return ;
}
int mid = (left+right) >> 1;
if(a <= mid) Updata(lson,a,l);//剪枝
else Updata(rson,a,l);
maxx[k][root] = max(maxx[k][root<<1],maxx[k][root<<1|1]);//父节点应为为子节点的最大的那个
}
double Find(int left, int right, int root, int k, int a, int b)
{
double maxn = 0;
if(a<=left && right<=b) return maxx[k][root];
int mid = (left+right) >> 1;
if(a <= mid) maxn = max(maxn,Find(lson,a,b));//剪枝
if(b > mid) maxn = max(maxn,Find(rson,a,b));
return maxn;
}
int main()
{
int t;
while(scanf("%d",&t),t)
{
char ch;
int h;
double a, l;
for(int i = 0; i <= 100; i++)
Build(0,1000,1,i);
while(t--)
{
getchar();
scanf("%c",&ch);
if(ch == 'I')
{
scanf("%d%lf%lf",&h,&a,&l);
h -= 100;//身高要减去100
Updata(0,1000,1,h,(int)(a*10),l);//活泼度要乘以10
}
else
{
int a, b; double x, y;
scanf("%d%d%lf%lf",&a,&b,&x,&y);
a -= 100; b -= 100;
if(a > b)
{
int temp = a; a = b; b = temp;
}
if(x > y)
{
double temp = x; x = y; y = temp;
}
double maxn = 0;
for(int k = a; k <= b; k++)
{
double temp = Find(0,1000,1,k,(int)(x*10),(int)(y*10));
if(temp > maxn) maxn = temp;
}
if(maxn) printf("%.1lf\n",maxn);
else printf("-1\n");
}
}
}
return 0;
}
HDU 1823 二维线段树
最新推荐文章于 2022-07-23 09:51:56 发布