目测为了做这道题我可能写了近千行代码。
刚开始的时候看出来这道题应该是一个二维的线段树,我没有做过二维的线段树,就在脑子里yy二维的线段树应该是什么样子。我当时想的情况是先对第一个关键字进行建树,结束之后再在第一个树的每一个叶节点中对第二个关键字建树。废了好大劲儿终于把代码敲出来,然后提交TLE。
我想了一下,觉得这样的话查询效率会很低,对于第一个关键字的区间内的每一个值都要查询到叶节点,然后对于每一个叶节点又要重新进行一次查询,一直查询到符合条件的区间。我又想了想,觉得应该对于第一棵树中的每一个节点建树,这样查询效率会高很多。然后又是重新敲代码,代码完成后出现了不知名错误,测试数据一直越界。debugN久后无奈放弃。
最后我去看了下别人的代码是怎么建树的,发现他们都是将子树的数据存入一个结构体中,其他地方和我的思路都一样。然后我用这种方法开始建树。
结果还是很凄凉,代码敲完,先是出现了不知名的爆栈错误,找到是因为一个递归条件没有敲好。之后发现有一组测试数据通不过,检查了半天代码,发现是因为在更新时我只对叶节点的子树进行了更新操作。正确的操作应该是对每一个节点的子树进行更新操作。修改后测试数据终于通过,然后提交又发生了最让人纠结的RE。
当时心都快碎了,这个RE浪费了我好长时间。最后终于想到是给出的检查区间有可能a1>a2,b1>b2,这时候应该将两个值交换。OMG!
然后提交,不再RE,改WA了。FML!
这时候我已经在这道题上耽误了一天半的时间,我也没有心情再去重新纠结一个可能非常坑爹的bug了。我直接去看了discuss,结果这个bug倒真是我的错。题目中的测试数据有可能有两个条件相同的女孩儿,只有幸福值不同,在这样的情况下,这个线段树不应该像一般的线段树那样用新值去取代旧值,而是将两者比较,保留较大的那个。
再然后提交,NA。
#include<stdio.h>
#include<string.h>
struct sub_tree
{
int l,r;
int max;
};
struct node
{
int x,y;
sub_tree b[4100];
}a[800];
int Max(int x,int y)
{
if(x>y)
return x;
else
return y;
}
void Sub_CreatTree(int t,int tt,int l,int r)
{
a[tt].b[t].l=l;
a[tt].b[t].r=r;
a[tt].b[t].max=-1;
if(l==r)
return ;
int temp=t*2;
int mid=(l+r)/2;
Sub_CreatTree(temp,tt,l,mid);
Sub_CreatTree(temp+1,tt,mid+1,r);
return ;
}
void CreatTree(int t,int x,int y,int l,int r)
{
a[t].x=x;
a[t].y=y;
Sub_CreatTree(1,t,l,r);
if(x==y)
return ;
int temp=t*2;
int mid=(x+y)/2;
CreatTree(temp,x,mid,l,r);
CreatTree(temp+1,mid+1,y,l,r);
return ;
}
void Sub_InsertTree(int t,int tt,int y,int z)
{
if(a[t].b[tt].l==a[t].b[tt].r)
{
if(a[t].b[tt].max<z)
a[t].b[tt].max=z;
return ;
}
int temp=tt*2;
int mid=(a[t].b[tt].l+a[t].b[tt].r)/2;
if(y<=mid)
Sub_InsertTree(t,temp,y,z);
else
Sub_InsertTree(t,temp+1,y,z);
a[t].b[tt].max=Max(a[t].b[temp].max,a[t].b[temp+1].max);
return ;
}
void InsertTree(int t,int xx,int y,int z)
{
Sub_InsertTree(t,1,y,z);
if(a[t].x==a[t].y)
return ;
int temp=t*2;
int mid=(a[t].x+a[t].y)/2;
if(xx<=mid)
InsertTree(temp,xx,y,z);
else
InsertTree(temp+1,xx,y,z);
return ;
}
int Sub_FindTree(int t,int tt,int l,int r)
{
int max=-1;
if(a[t].b[tt].l==a[t].b[tt].r)
return a[t].b[tt].max;
int temp=tt*2;
int mid=(a[t].b[tt].l+a[t].b[tt].r)/2;
if(r<=mid)
max=Max(max,Sub_FindTree(t,temp,l,r));
else if(l>mid)
max=Max(max,Sub_FindTree(t,temp+1,l,r));
else
{
max=Max(max,Sub_FindTree(t,temp,l,mid));
max=Max(max,Sub_FindTree(t,temp+1,mid+1,r));
}
return max;
}
int FindTree(int t,int x,int y,int l,int r)
{
int max=-1;
if(a[t].x==x&&a[t].y==y)
{
max=Max(max,Sub_FindTree(t,1,l,r));
return max;
}
int temp=t*2;
int mid=(a[t].x+a[t].y)/2;
if(y<=mid)
max=Max(max,FindTree(temp,x,y,l,r));
else if(x>mid)
max=Max(max,FindTree(temp+1,x,y,l,r));
else
{
max=Max(max,FindTree(temp,x,mid,l,r));
max=Max(max,FindTree(temp+1,mid+1,y,l,r));
}
return max;
}
int main()
{
int T;
while(scanf("%d",&T),T)
{
CreatTree(1,0,100,0,1000);
getchar();
while(T--)
{
char c;
scanf("%c",&c);
if(c=='I')
{
int x,y,z;
double a,b;
scanf("%d%lf%lf",&x,&a,&b);
x-=100;
getchar();
y=(int)(a*10);
z=(int)(b*10);
InsertTree(1,x,y,z);
}
else if(c=='Q')
{
int x,y;
double a,b;
int l,r;
scanf("%d%d%lf%lf",&x,&y,&a,&b);
x-=100;
y-=100;
getchar();
l=(int)(a*10);
r=(int)(b*10);
int temp;
if(x>y)
{
temp=x;
x=y;
y=temp;
}
if(l>r)
{
temp=l;
l=r;
r=temp;
}
int max=-1;
max=FindTree(1,x,y,l,r);
/*
double ans;
ans=max*1.0;
printf("%.1f\n",ans);
*/
if(max<0)
printf("-1\n");
else
{
double ans;
ans=max*1.0/10;
printf("%.1f\n",ans);
}
}
}
}
return 0;
}