hdu 1823 Luck and Love(二维线段树)

来源:互联网 发布:mysql触发器 教程 编辑:程序博客网 时间:2024/05/15 01:47

目测为了做这道题我可能写了近千行代码。

刚开始的时候看出来这道题应该是一个二维的线段树,我没有做过二维的线段树,就在脑子里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;}


原创粉丝点击