poj-1151-Atlantis-线段树求面积并

很裸的线段树求面积并。

坐标需要离散化一下。

#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<map>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define maxn 11000
#define mem(a,b) (memset(a),b,sizeof(a))
#define lmin 1
#define rmax len
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define root lmin,rmax,1
#define now l,r,rt
#define int_now int l,int r,int rt
#define INF 99999999
#define LL long long
#define mod 10007
#define eps 1e-6
#define zero(x) (fabs(x)<eps?0:x)
map<double,int>mp;
double du[4010];
int len;
struct list
{
    double x1,y1;
    double x2,y2;
}node[maxn];
struct linen
{
    double y1,y2;
    int leap;
    double x;
    friend bool operator <(const linen &a,const linen &b)
    {
        if(zero(a.x-b.x)!=0) return a.x<b.x;
        else return a.leap>b.leap;
    }
}line[maxn*2];
double num[maxn*4*4*2];
int cover[maxn*4*4*2];
void push_up(int_now)
{
    if(cover[rt]==0)
    {
        num[rt]=num[rt<<1]+num[rt<<1|1];
    }
    if(cover[rt]>=1)
    {
        num[rt]=du[r+1]-du[l];
    }
  //  cout<<rt<<" "<<du[l]<<"===="<<du[r+1]<<" "<<cover[rt]<<" "<<num[rt]<<" "<<sum[rt]<<endl;
}
void push_down(int_now)
{

}
void creat(int_now)
{
    memset(cover,0,sizeof(cover));
    memset(num,0,sizeof(num));
}
void updata(int ll,int rr,int x,int_now)
{
    if(ll>r||rr<l)return;
    if(ll<=l&&rr>=r)
    {
       // cout<<l<<" "<<r<<"-"<<du[l]<<" "<<du[r+1]<<" "<<endl;
        cover[rt]+=x;
        push_up(now);
        return;
    }
    updata(ll,rr,x,lson);
    updata(ll,rr,x,rson);
    push_up(now);
}
int main()
{
    int t,n,s;
    int cas=0;
    while(~scanf("%d",&n)&&n)
    {
        cas++;
        s=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%lf%lf%lf%lf",&node[i].x1,&node[i].y1,&node[i].x2,&node[i].y2);
            du[++s]=node[i].x1;
            du[++s]=node[i].y1;
            du[++s]=node[i].x2;
            du[++s]=node[i].y2;
            line[i*2-1].x=node[i].x1;
            line[i*2-1].y1=node[i].y1;
            line[i*2-1].y2=node[i].y2;
            line[i*2-1].leap=1;
            line[i*2].x=node[i].x2;
            line[i*2].y1=node[i].y1;
            line[i*2].y2=node[i].y2;
            line[i*2].leap=-1;
        }
        sort(line+1,line+n*2+1);
        sort(du+1,du+s+1);
        du[0]=-1;
        len =0;
        mp.clear();
        for(int i=1;i<=s;i++)
        {
            if(du[i]!=du[i-1])
            {
                mp[du[i]]=++len;
                du[len]=du[i];
            }
        }
        creat(root);
        double st=0;
        double are=0.0;
        for(int i=1;i<=len;i++)
        {
           // cout<<i<<"----"<<du[i]<<endl;
        }
        len--;
       // cout<<1<<" "<<len<<" "<<1<<" "<<endl;
        for(int i=1;i<=n*2;i++)
        {
            int l,r;
            l=mp[line[i].y1];
            r=mp[line[i].y2];
            if(zero(line[i].x-st)!=0)
            {
                are+=(line[i].x-st)*num[1];
                st=line[i].x;
            }
           // cout<<line[i].x<<" "<<line[i].y1<<" "<<line[i].y2<<" "<<" "<<line[i].leap<<endl;
            updata(l,r-1,line[i].leap,root);
            //cout<<l<<" "<<r<<" "<<are<<endl;
        }
        printf("Test case #%d\n",cas);
        printf("Total explored area: %.2f\n\n",are);
    }
    return 0;
}

poj-1151-Atlantis-线段树求面积并

时间: 2024-10-01 21:25:40

poj-1151-Atlantis-线段树求面积并的相关文章

POJ&#183;1151 Atlantis&#183;线段树求矩形面积并

题目在这:http://poj.org/problem?id=1151 Atlantis Time Limit: 1000MS   Memory Limit: 10000K Description There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the is

POJ 1151 Atlantis 线段树+离散化

题目链接:http://poj.org/problem?id=1151  http://acm.hdu.edu.cn/showproblem.php?pid=1542 题目大意:给你几个矩形的坐标,求他们的面积的并. 解题思路:可以参考http://www.cnblogs.com/kuangbin/archive/2011/08/16/2140544.html,实际上就是一个方向直接算出,另一个方向使用线段树维护已经覆盖的底边的长度.具体操作不算复杂:假想一条扫描下从下往上开始进行扫描,初始时候

POJ 1151 Atlantis( 线段树 + 扫描线 )

一维离散化, 扫描线扫另一维, 用线段树维护 POJ建议交C++...G++貌似double要用%f ? 反正同一份代码C++AC,G++WA ------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 109; struct Line { double p,

hdu 1542 Atlantis 线段树求面积并,,,尼玛数据真坑人,数组千万不能开小!

Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7815    Accepted Submission(s): 3420 Problem Description There are several ancient Greek texts that contain descriptions of the fabled i

poj 1151 Atlantis (线段树+扫描线+离散化)

Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18061   Accepted: 6873 Description There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of

poj 1151 Atlantis (线段树+扫描线)

Description There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your friend

hdu 1542 Atlantis(线段树&amp;扫描线&amp;面积并)

Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6386    Accepted Submission(s): 2814 Problem Description There are several ancient Greek texts that contain descriptions of the fabled i

POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并

题意:给出矩形两对角点坐标,求矩形面积并. 解法:线段树+离散化. 每加入一个矩形,将两个y值加入yy数组以待离散化,将左边界cover值置为1,右边界置为2,离散后建立的线段树其实是以y值建的树,线段树维护两个值:cover和len,cover表示该线段区间目前被覆盖的线段数目,len表示当前已覆盖的线段长度(化为离散前的真值),每次加入一条线段,将其y_low,y_high之间的区间染上line[i].cover,再以tree[1].len乘以接下来的线段的x坐标减去当前x坐标,即计算了一部

hdu(1255)——覆盖的面积(线段树求面积交)

给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 虽说覆盖两次区域的面积,但是这道题实际上就是求矩形的面积交. 膜拜能够想出这种解法的神牛,竟然能把实际的东西用这么抽象的语言表示出来,实在是佩服,现在关于扫描线的题才做了几道,没有对其深刻理解,但是多练总可以理解的,奋斗吧!!ACMer!!我是永远不会服输的.加油! 下面还是附上题解,写的不够详细清楚还请多多见谅. 首先我想说我是看了别人的博客学了思路,然后按照别人的代码来模仿写的. 这里推荐:http://www.cnblogs.

HDU 1828 / POJ 1177 Picture --线段树求矩形周长并

题意:给n个矩形,求矩形周长并 解法:跟求矩形面积并差不多,不过线段树节点记录的为: len: 此区间线段长度 cover: 此区间是否被整个覆盖 lmark,rmark: 此区间左右端点是否被覆盖 num: 此区间分离开的线段的条数 重点在转移的地方,不难理解. 代码: #include <iostream> #include <cmath> #include <iostream> #include <cstdio> #include <cstrin