思路:很裸地二维线段树,就是维护区间最大值
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=1010;
int M;
char op[5];
int H,H1,H2,A1,A2,A,L, ans;
struct IntervalTree
{
int maxv[110<<3][maxn<<3];
void build()
{
memset(maxv,-1,sizeof(maxv));
}
void updateY(int xo,int o,int l,int r,int x,int flag)
{
if(l==r)
{
if(flag!=-1){maxv[xo][o]=max(maxv[xo][o],x);}//注意如果两个女孩的身高和活跃度相同,取最大值
else maxv[xo][o]=max(maxv[xo<<1][o],maxv[xo<<1|1][o]);
return;
}
int mid=(l+r)>>1;
if(A<=mid)updateY(xo,o<<1,l,mid,x,flag);
else updateY(xo,o<<1|1,mid+1,r,x,flag);
maxv[xo][o]=max(maxv[xo][o<<1],maxv[xo][o<<1|1]);
}
void updateX(int o,int l,int r,int x)
{
if(l==r)
{
updateY(o,1,0,1001,x,1);
return;
}
int mid=(l+r)>>1;
if(H<=mid)updateX(o<<1,l,mid,x);
else updateX(o<<1|1,mid+1,r,x);
updateY(o,1,0,1001,x,-1);
}
void queryY(int xo,int o,int l,int r)
{
if(A1<=l&&r<=A2)
{
ans=max(ans,maxv[xo][o]);
return ;
}
int mid=(l+r)>>1;
if(A1<=mid)queryY(xo,o<<1,l,mid);
if(A2>mid)queryY(xo,o<<1|1,mid+1,r);
}
void queryX(int o,int l,int r)
{
if(H1<=l&&r<=H2)
{
queryY(o,1,0,1001);
return ;
}
int mid=(l+r)>>1;
if(H1<=mid)queryX(o<<1,l,mid);
if(H2>mid)queryX(o<<1|1,mid+1,r);
}
}tree;
int main()
{
freopen("in.txt","r",stdin);
while(scanf("%d",&M)!=EOF,M)
{
tree.build();
while(M--)
{
scanf("%s",op);
if(op[0]=='I')
{
double a,l;
scanf("%d%lf%lf",&H,&a,&l);
L=l*10;
H-=100;
A=a*10;
tree.updateX(1,0,101,L);
}
else if(op[0]=='Q')
{
double a1,a2;
scanf("%d%d%lf%lf",&H1,&H2,&a1,&a2);
A1=int(a1*10),A2=int(a2*10);
H1-=100,H2-=100;
if(H1>H2)swap(H1,H2);
if(A1>A2)swap(A1,A2);
ans=-1;
tree.queryX(1,0,101);
if(ans>=0) printf("%.1lf\n",ans/10.0);
else printf("-1\n");
}
}
}
return 0;
}