hdu 1542 Atlantis 二维线段树

网上这题好像没有用二维线段树做的,今天写一个试了试。 171MS,还行。

用G++提交的,C++一直

 

 

 

#include<iostream>
#include<algorithm>
#include<map>
#include<iomanip>

using namespace std;

map<double,int> mx;
map<int,double> subx;
map<double,int> my;
map<int,double> suby;

double tx[250];
double ty[250];

struct rec
{
    double x1;
    double y1;

    double x2;
    double y2;
}p[110];

struct sub_tree
{
    int left;
    int right;
    int mid;
    int flag;
    double total;
};

struct up_tree
{
    int left;
    int right;
    int mid;
    int flag;
    double total;
    struct sub_tree sub[200*4];
}up[200*4];

int n;
int countt;
int t1,t2;   //上树和下树的最大值,即x,y坐标的最大个数

void create_up_tree(int l,int r,int now);
void create_sub_tree(int l,int r,int upid,int now);
void update_up(int l,int r,int yl,int yr,int now);
void update_sub(int l,int r,int upid,int now);

int T;


int main()
{
    T=1;
    while(cin>>n,n)
    {
        mx.clear();
        my.clear();
        countt=0;
        for(int i=0;i<n;i++)
        {
            cin>>p[i].x1>>p[i].y1>>p[i].x2>>p[i].y2;

            tx[countt]=p[i].x1;
            ty[countt++]=p[i].y1;
            tx[countt]=p[i].x2;
            ty[countt++]=p[i].y2;
        }

        sort(tx,tx+countt);
        sort(ty,ty+countt);


        t1=0,t2=0;
        for(int i=0;i<countt;i++)
        {
            if(!mx[tx[i]])
            {
                subx[t1]=tx[i];
                mx[tx[i]]=t1++;
            }
            if(!my[ty[i]])
            {
                suby[t2]=ty[i];
                my[ty[i]]=t2++;
            }
        }
        create_up_tree(0,205,1);


/*        for(i=0;i<n;i++)
        {
            cout<<mx[p[i].x1]<<" "<<my[p[i].y1]<<" "<<mx[p[i].x2]<<" "<<my[p[i].y2]<<endl;
        }
        for(i=0;i<n;i++)
        {
            cout<<subx[mx[p[i].x1]]<<" "<<suby[my[p[i].y1]]<<" "<<subx[mx[p[i].x2]]<<" "<<suby[my[p[i].y2]]<<endl;
        }
*/
        for(int i=0;i<n;i++)
        {
            if(p[i].x1==p[i].x2 || p[i].y1==p[i].y2)
                continue;
            update_up( mx[p[i].x1] , mx[p[i].x2] , my[p[i].y1] , my[p[i].y2] ,1);
        }

        cout<<"Test case #"<<T++<<endl;
        cout<<"Total explored area: "<<fixed<<setprecision(2)<<up[1].total<<endl<<endl; 
    }

    return 0;
}


void create_up_tree(int l,int r,int now)
{
    up[now].left=l;
    up[now].right=r;
    up[now].total=0;
//    up[now].flag=0;
    create_sub_tree(0,205,now,1);

    if(l+1==r)
        return ;

    int mid=(l+r)>>1;
    up[now].mid=mid;

    create_up_tree(l,mid,now*2);
    create_up_tree(mid,r,now*2+1);
}

void create_sub_tree(int l,int r,int upid,int now)
{
    up[upid].sub[now].left=l;
    up[upid].sub[now].right=r;
    up[upid].sub[now].total=0;
//    up[upid].sub[now].flag=0;

    if(l+1==r)
        return ;

    int mid=(l+r)>>1;

    up[upid].sub[now].mid=mid;

    create_sub_tree(l,mid,upid,now*2);
    create_sub_tree(mid,r,upid,now*2+1);
}

void update_up(int l,int r,int yl,int yr,int now)
{
    if(l+1==r && l==up[now].left && r==up[now].right)
    {
        update_sub(yl,yr,now,1);

        up[now].total= (subx[r]-subx[l]) * up[now].sub[1].total ;
        return ;
    }

    if(up[now].mid>=r)
    {
        update_up(l,r,yl,yr,now*2);
        up[now].total=up[now*2].total+up[now*2+1].total;
    }
    else if(up[now].mid<=l)
    {
        update_up(l,r,yl,yr,now*2+1);
        up[now].total=up[now*2].total+up[now*2+1].total;
    }
    else
    {
        update_up(l,up[now].mid,yl,yr,now*2);
        update_up(up[now].mid,r,yl,yr,now*2+1);
        up[now].total=up[now*2].total+up[now*2+1].total;
    }
}

void update_sub(int l,int r,int upid,int now)
{
    if(l+1==r && l==up[upid].sub[now].left && r==up[upid].sub[now].right)
    {
        up[upid].sub[now].total=suby[r]-suby[l];
        return ;
    }


    if(up[upid].sub[now].mid>=r)
    {
        update_sub(l,r,upid,now*2);
        up[upid].sub[now].total=up[upid].sub[now*2].total+up[upid].sub[now*2+1].total;
    }
    else if(up[upid].sub[now].mid<=l)
    {
        update_sub(l,r,upid,now*2+1);
        up[upid].sub[now].total=up[upid].sub[now*2].total+up[upid].sub[now*2+1].total;
    }
    else
    {
        update_sub(l,up[upid].sub[now].mid,upid,now*2);
        update_sub(up[upid].sub[now].mid,r,upid,now*2+1);
        up[upid].sub[now].total=up[upid].sub[now*2].total+up[upid].sub[now*2+1].total;
    }
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值