学习二维线段树,需有一维线段树的基础。倘若对一维线段树还不是很了解的同学可以点开这个链接看看。
http://blog.csdn.net/jobsandczj/article/details/47808213
Luck and Love
Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5884 Accepted Submission(s): 1472
而是我在你面前
可你却不知道我爱你
―― 张小娴
前段日子,枫冰叶子给Wiskey做了个征婚启事,聘礼达到500万哦,天哪,可是天文数字了啊,不知多少MM蜂拥而至,顿时万人空巷,连扫地的大妈都来凑热闹来了。―_―|||
由于人数太多,Wiskey实在忙不过来,就把统计的事情全交给了枫冰叶子,自己跑回家休息去了。这可够枫冰叶子忙的了,他要处理的有两类事情,一是得接受MM的报名,二是要帮Wiskey查找符合要求的MM中缘分最高值。
接下来是一个操作符C。
当操作符为‘I’时,表示有一个MM报名,后面接着一个整数,H表示身高,两个浮点数,A表示活泼度,L表示缘分值。 (100<=H<=200, 0.0<=A,L<=100.0)
当操作符为‘Q’时,后面接着四个浮点数,H1,H2表示身高区间,A1,A2表示活泼度区间,输出符合身高和活泼度要求的MM中的缘分最高值。 (100<=H1,H2<=200, 0.0<=A1,A2<=100.0)
所有输入的浮点数,均只有一位小数。
对查找不到的询问,输出-1。
8 I 160 50.5 60.0 I 165 30.0 80.5 I 166 10.0 50.0 I 170 80.5 77.5 Q 150 166 10.0 60.0 Q 166 177 10.0 50.0 I 166 40.0 99.9 Q 166 177 10.0 50.0 0
80.5 50.0 99.9
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
double a[220][4040];
int n;
//H范围[0,200]
void build(int l,int r, int id,int H) //初始 rt==1 H==i;
{
a[H][id] = 0; //刚开始全部赋值为0
if(l == r)
{
a[H][id] = 0;
return ;
}
int m = (l + r) >> 1; //除以2
build(l,m,id<<1,H);
build(m+1,r,(id<<1)+1,H);
}
//p->活泼度 q->缘分值 H->身高
void update(int l,int r,int p,double q,int id,int H) //update(0,1000,(int)(aa*10),l,1,x);
//x->身高 aa->活泼度 l->缘分值
{
if(l == r)
{
//H表示身高
a[H][id] = max(a[H][id],q); //q->缘分值 建树时a[][]里的值清零
return;
}
int m = (l + r) >> 1;
if(p <= m) //p->活泼度 活泼度与id有联系
update(l,m,p,q,id<<1,H);
else
update(m+1,r,p,q,(id<<1)+1,H);
a[H][id] = max(a[H][id<<1],a[H][(id<<1)+1]); //找到缘分值最大的
}
//p-q表示活泼度要求范围 H->身高
double query(int l,int r,int p,int q,int id,int H) //query(0,1000,(int)(a1*10),(int)(a2*10),1,i);
{
if(p <= l && q >= r)
{
return a[H][id];
}
int m = (l + r) >> 1;
double ret = 0;
if(p <= m) //左半段
{
ret = max(ret,query(l,m,p,q,id<<1,H));
}
if(q > m) //右半段
{
ret = max(ret,query(m+1,r,p,q,(id<<1)+1,H));
}
return ret;
}
int main()
{
int t,x,h,h1,h2,i;
double aa,a1,a2,l;
char str[10];
while(scanf("%d",&t),t)
{
for(i = 0;i <= 200; i++) //建树
build(0,1000,1,i);
while(t--)
{
scanf("%s",str);
if(str[0] == 'I')
{
scanf("%d %lf %lf",&x,&aa,&l);//x->身高 aa->活泼度 l->缘分值
update(0,1000,(int)(aa*10),l,1,x); //由于活泼度小数后最多一位,所以乘以10当做整数处理
}
else
{
scanf("%d %d %lf %lf",&h1,&h2,&a1,&a2);
if(h1 > h2)
{
swap(h1,h2);
}
if(a1 > a2)
{
swap(a1,a2);
}
double max = 0;
for(i = h1;i <= h2; i++) //身高范围用来遍历
{ //a1,a2是活泼度 1表示结点id
double k = query(0,1000,(int)(a1*10),(int)(a2*10),1,i);
if(max < k)
max = k;
}
if(max == 0)
printf("-1\n");
else
printf("%.1lf\n",max);
}
}
}
return 0;
}