//4681418 2011-09-30 12:26:14 Accepted 1823 140MS 7520K 3762 B C++ nkhelloworld //4681419 2011-09-30 12:26:40 Accepted 1823 203MS 7588K 3762 B G++ nkhelloworld /* 二维线段树,一个线段树中套一个线段树,求区间最大值 再次强调要注意区间范围是不是反着的,如h1 > h2时应swap 注意读入浮点数的时候可能产生精度误差,*10再转int可能就错了 此题,如果不加eps,在C++下可以AC,在G++下是WA */ #include <cstdio> #include <iostream> #define eps 1e-4 using namespace std; #define MAXH 110 #define MAXA 1010 struct SUBTREE { int lt,rt; double maxval; }; struct MAINTREE { int lt,rt; SUBTREE subtree[MAXA*4]; }tree[MAXH*4]; void buildsubtree(int paroot,int root,int lt,int rt) { tree[paroot].subtree[root].lt = lt; tree[paroot].subtree[root].rt = rt; tree[paroot].subtree[root].maxval = -1.0; if(lt == rt) return ; int mid = (lt + rt)>>1; buildsubtree(paroot,root<<1,lt,mid); buildsubtree(paroot,root<<1|1,mid+1,rt); } void buildmaintree(int root,int lt,int rt) { tree[root].lt = lt; tree[root].rt = rt; buildsubtree(root,1,0,1000); if(lt == rt) return ; int mid = (lt + rt)>>1; buildmaintree(root<<1,lt,mid); buildmaintree(root<<1|1,mid+1,rt); } void update2(int paroot,int root,int h,int active,double love) { if(tree[paroot].subtree[root].maxval < love) tree[paroot].subtree[root].maxval = love; if(tree[paroot].subtree[root].lt == tree[paroot].subtree[root].rt) return ; int mid = (tree[paroot].subtree[root].lt + tree[paroot].subtree[root].rt)>>1; if(active <= mid) update2(paroot,root<<1,h,active,love); else update2(paroot,root<<1|1,h,active,love); } void update(int root,int h,int active,double love) { update2(root,1,h,active,love); if(tree[root].lt == tree[root].rt) return ; int mid = (tree[root].lt + tree[root].rt)>>1; if(h <= mid) update(root<<1,h,active,love); else update(root<<1|1,h,active,love); } double query2(int paroot,int root,int h1,int h2,int a1,int a2) { if(tree[paroot].subtree[root].lt == a1 && tree[paroot].subtree[root].rt == a2) return tree[paroot].subtree[root].maxval; int mid = (tree[paroot].subtree[root].lt + tree[paroot].subtree[root].rt)>>1; if(a2 <= mid) return query2(paroot,root<<1,h1,h2,a1,a2); else if(a1 > mid) return query2(paroot,root<<1|1,h1,h2,a1,a2); else return max(query2(paroot,root<<1,h1,h2,a1,mid), query2(paroot,root<<1|1,h1,h2,mid+1,a2) ); } double query(int root,int h1,int h2,int a1,int a2) { if(tree[root].lt == h1 && tree[root].rt == h2) return query2(root,1,h1,h2,a1,a2); int mid = (tree[root].lt + tree[root].rt)>>1; if(h2 <= mid) return query(root<<1,h1,h2,a1,a2); else if(h1 > mid) return query(root<<1|1,h1,h2,a1,a2); else return max( query(root<<1,h1,mid,a1,a2), query(root<<1|1,mid+1,h2,a1,a2) ); } int main() { int m,i,j,h1,h2; double a,love,a1,a2; char op[5]; while(scanf("%d",&m),m) { buildmaintree(1,0,100); while(m--) { scanf("%s",op); if(op[0] == 'I') { scanf("%d%lf%lf",&h1,&a,&love); h1 = h1 - 100; a += eps; update(1,h1,(int)(a*10),love); } else { scanf("%d%d%lf%lf",&h1,&h2,&a1,&a2); if(h1 > h2) swap(h1,h2); if(a1 > a2) swap(a1,a2); h1 -= 100; h2 -= 100; a1 += eps; a2 += eps; double ans = query(1,h1,h2,(int)(a1*10),(int)(a2*10)); if(ans < 0) printf("-1\n"); else printf("%.1f\n",ans); } } } return 0; }