Problem Description
世界上上最远的距离不是相隔天涯海角
而是我在你面前
可你却不知道我爱你
―― 张小娴
前段日子,枫冰叶子给Wiskey做了个征婚启事,聘礼达到500万哦,天哪,可是天文数字了啊,不知多少MM蜂拥而至,顿时万人空巷,连扫地的大妈都来凑热闹来了。―_―|||
由于人数太多,Wiskey实在忙不过来,就把统计的事情全交给了枫冰叶子,自己跑回家休息去了。这可够枫冰叶子忙的了,他要处理的有两类事情,一是得接受MM的报名,二是要帮Wiskey查找符合要求的MM中缘分最高值。
而是我在你面前
可你却不知道我爱你
―― 张小娴
前段日子,枫冰叶子给Wiskey做了个征婚启事,聘礼达到500万哦,天哪,可是天文数字了啊,不知多少MM蜂拥而至,顿时万人空巷,连扫地的大妈都来凑热闹来了。―_―|||
由于人数太多,Wiskey实在忙不过来,就把统计的事情全交给了枫冰叶子,自己跑回家休息去了。这可够枫冰叶子忙的了,他要处理的有两类事情,一是得接受MM的报名,二是要帮Wiskey查找符合要求的MM中缘分最高值。
Input
本题有多个测试数据,第一个数字M,表示接下来有连续的M个操作,当M=0时处理中止。
接下来是一个操作符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)
所有输入的浮点数,均只有一位小数。
接下来是一个操作符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)
所有输入的浮点数,均只有一位小数。
Output
对于每一次询问操作,在一行里面输出缘分最高值,保留一位小数。
对查找不到的询问,输出-1。
对查找不到的询问,输出-1。
Sample Input
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
Sample Output
80.5 50.0 99.9
#include<iostream>
#include<cstdio>
using namespace std;
float meili[5005][5005<<2]; // 这里二维表示身高和活力,结果是缘分
int N;
double max(double a, double b)
{
return a>b ? a : b;
}
void build2(int l, int r, int deep, int rt) //在活力方向上初始化。
{
meili[deep][rt] = -1.0;
if (l == r)
return;
int mid = (l + r) >> 1;
build2(l, mid, deep, rt << 1);
build2(mid + 1, r, deep, rt << 1 | 1);
}
void build(int l, int r, int root) //在每一高度上,转移给活力进行初始化
{
build2(0, 1000, root, 1);
if (l == r)
return;
int mid = (l + r) >> 1;
build(l, mid, root << 1);
build(mid + 1, r, root << 1 | 1);
}
void I2(int act, float love, int l, int r, int deep, int rt) //对插入量进行活力上的定位,并对相关量更新
{
meili[deep][rt] = max(love, meili[deep][rt]); //对根进行更新
if (l == r)
return;
int mid = (l + r) >> 1;
if (mid >= act)
I2(act, love, l, mid, deep, rt << 1);
else
I2(act, love, mid + 1, r, deep, rt << 1 | 1);
meili[deep][rt] = max(meili[deep][rt << 1], meili[deep][rt << 1 | 1]); //对根进行更新
}
void I(int h, int act, float love, int l, int r, int rt) //对插入量进行一次高度上的定位
{
I2(act, love, 0, 1000, rt, 1);
if (l == r)
return;
int mid = (l + r) >> 1;
if (mid >= h)
I(h, act, love, l, mid, rt << 1);
else
I(h, act, love, mid + 1, r, rt << 1 | 1);
}
float Q2(int act1, int act2, int l, int r, int deep, int rt) //要求【act1,act2】范围,目前以rt为根是【l,r】范围
{
if (act1 <= l&&r <= act2)
return meili[deep][rt];
int mid = (l + r) >> 1;
if (mid >= act2)
return Q2(act1, act2, l,mid, deep, rt << 1);
else
if (mid < act1) //细节这里不能取等号,mid==act2,但是不能将问题递归给右子树
return Q2(act1, act2,mid+1,r, deep, rt << 1 | 1 );
return max(Q2(act1, act2, l, mid, deep, rt << 1), Q2(act1, act2, mid + 1, r, deep, rt << 1 |1));
}
float Q(int h1, int h2, int act1, int act2, int l, int r, int rt) //对高度进行定位,并将得到的根节点传给Q2的深度
{
if (h1 <= l&&r <= h2)
return Q2(act1, act2, 0, 1000, rt, 1);
int mid = (l + r) >> 1;
if (h1>mid)
return Q(h1, h2, act1, act2, mid + 1, r, rt << 1 | 1);
else
if (h2 <= mid)
return Q(h1, h2, act1, act2, l, mid, rt << 1);
else
return max(Q(h1, h2, act1, act2, l, mid, rt << 1), Q(h1, h2, act1, act2, mid+ 1, r, rt << 1 | 1));
}
int main()
{
//freopen("in.txt", "r", stdin);
while (scanf("%d", &N) != EOF&&N)
{
build(100, 200, 1);
char ch;
while (N--)
{
cin >> ch;
if (ch == 'I')
{
int h;
float x, y;
cin >> h >> x >> y;
I(h, (int)(x * 10), y, 100, 200, 1);
}
else
{
int h1, h2;
float x1, x2;
cin >> h1 >> h2 >> x1 >> x2;
if (h1>h2) {
int temp = h1; h1 = h2; h2 = temp;
}
if (x1>x2) {
float temp = x1; x1 = x2; x2 =temp;
}
float ans = Q(h1, h2, (int)(x1 * 10), (int)(x2* 10), 100, 200, 1);
if (ans == -1.0) printf("-1\n");
else printf("%.1lf\n", ans);
}
}
}
//system("pause");
return 0;
}