【BZOJ】1382: [Baltic2001]Mars Maps (线段树+扫描线)

1382: [Baltic2001]Mars Maps

Time Limit: 5 Sec  Memory Limit: 64 MB

Description

给出N个矩形,N<=10000.其坐标不超过10^9.求其面积并

Input

先给出一个数字N,代表有N个矩形. 接下来N行,每行四个数,代表矩形的坐标.

Output

输出面积并

Sample Input

2
10 10 20 20
15 15 25 30

Sample Output

225

本以为是傻逼题,没想到不容易啊~

线段树+扫描线+离散化(也可以不用?!)

如果接触过扫描线,想到解法还比较容易。不过写起来细节重重啊~~~

前几次T掉了,然后调啊调终于A调。。。

虽然A掉了,不过一路坎坷,有些地方改的很玄乎。

还需要好好体会!555

sorry,写的太累,懒得描述了,详见代码吧。。。

#include<iostream>
#include<fstream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<vector>
#include<queue>
#include<deque>
#include<utility>
#include<map>
#include<set>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<functional>
#include<sstream>
#include<cstring>
#include<bitset>
#include<stack>
using namespace std;

int n,x1,y1x,x2,y2,ans,cnt;
struct sdt
{
    int l,r,y,flag;
}line[500005];
int old[500005],lef[500005],rig[500005],sum[500005],cntx[500005],ll[500005],rr[500005];

bool cmp(sdt x,sdt y)
{
    return x.y<y.y;
}

int read()
{
    int x=0;char c=getchar();
    while(c<48||c>57)c=getchar();
    while(c>47&&c<58)x*=10,x+=c-48,c=getchar();
    return x;
}

void check(int x)
{
	if(cntx[x])sum[x]=rr[x]-ll[x];
	else if(rig[x]-lef[x]==1)sum[x]=0;
	else sum[x]=sum[x*2]+sum[x*2+1];
}

void build(int root,int l,int r)
{
    lef[root]=l;
    rig[root]=r;
    ll[root]=old[l];
    rr[root]=old[r];
    sum[root]=0;
    cntx[root]=0;
    if(l+1==r)return ;
    int mid=(l+r)/2;
    build(root*2,l,mid);
    build(root*2+1,mid,r);
}

void update(int root,sdt x)
{
    if(x.l==ll[root] && x.r==rr[root])
    {
    	cntx[root]+=x.flag;
        check(root);
        return ;
    }
    if(x.l>=ll[root*2+1])update(root*2+1,x);
	else if(x.r<=rr[root*2])update(root*2,x);
	else
	{
		sdt xx;
		xx=x;
        xx.r=rr[root*2];
        update(root*2,xx);
        xx=x;
        xx.l=ll[root*2+1];
        update(root*2+1,xx);
	}
    check(root);
}

int main()
{
    n=read();
    for(int i=1;i<=n;i++)
    {
        x1=read();
        y1x=read();
        x2=read();
        y2=read();
        line[++cnt].y=y1x;
        line[cnt].l=x1;
        line[cnt].r=x2;
        line[cnt].flag=1;
        old[cnt]=x1;
        line[++cnt].y=y2;
        line[cnt].l=x1;
        line[cnt].r=x2;
        line[cnt].flag=-1;
        old[cnt]=x2;
    }
    sort(line+1,line+cnt+1,cmp);
	sort(old+1,old+cnt+1);
    build(1,1,cnt);
    update(1,line[1]);
    for(int i=2;i<=cnt;i++)
    {
        ans+=sum[1]*(line[i].y-line[i-1].y);
        update(1,line[i]);
    }
    printf("%d\n",ans);
    return 0;
}

  

时间: 2024-10-04 15:38:48

【BZOJ】1382: [Baltic2001]Mars Maps (线段树+扫描线)的相关文章

BZOJ 4059 Cerc2012 Non-boring sequences 线段树+扫描线

题目大意:定义一个序列为[不无聊的]当且仅当这个序列的任意一个区间都存在一个数只出现过一次,给定一个序列,要求判断这个序列是否是[不无聊的] 定义lasti表示第i个元素上一次出现的位置(第一次出现则为0),nexti表示第i个元素下一次出现的位置(最后一次出现则为n+1),那么这个元素能成为某个区间仅出现一次的数,当且仅当这个区间的左端点在[lasti+1,i]之间,右端点在[i,nexti?1]之间 我们可以将区间的左右端点放在二维平面上,那么一个元素产生的贡献是一个矩形,我们要确定的是所有

bzoj1382: [Baltic2001]Mars Maps 2011-12-20

1382: [Baltic2001]Mars Maps Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 85  Solved: 38 [Submit][Status][Discuss] Description 给出N个矩形,N<=10000.其坐标不超过10^9.求其面积并 Input 先给出一个数字N,代表有N个矩形. 接下来N行,每行四个数,代表矩形的坐标. Output 输出面积并 Sample Input 2 10 10 20 20 15 1

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

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

HDU 1542 Atlantis(线段树扫描线)

http://acm.hdu.edu.cn/showproblem.php?pid=1542 Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6788    Accepted Submission(s): 2970 Problem Description There are several ancient Greek

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

hdu 1542 Atlantis (线段树+扫描线)

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

HDU 4419 Colourful Rectangle --离散化+线段树扫描线

题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何维护每种颜色的长度着实让我伤透了脑筋.后来看了一位朋友的题解,才幡然醒悟. 开始想到了用二进制表示颜色,R用001表示,G用010表示,B用100表示.那么就可以用十进制1~7表示7种不同颜色了. 维护 cov[rt][1~3] 表示此区间内3种原色各有多少个, Len[rt][i]表示每种颜色的长

sgu316Kalevich Strikes Back(线段树+扫描线)

做法:总体想法是求出一个矩形的面积以及它所包含的矩形,然后用自己的面积减掉所包含的.主要问题是怎样求解它所包含的矩形. 因为是没有相交点的,可以利用扫描线的方法去做,类似染色,当前段如果是x色,也就是第x个矩形,那么再把他染成y颜色时,说明x包含y,而当扫到y的上边时,这一段又恢复到x色.标记一下被包含的矩形,记录所包含的矩形. 因为会有恢复染色操作,up需要时时更新,左儿子和右儿子一样颜色时就可以合并为一段. 1 ; 2 } 3 void down(int w) 4 { 5 if(s[w]!=

hdu1255 覆盖的面积 线段树-扫描线

矩形面积并 线段树-扫描线裸题 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<math.h> 5 using namespace std; 6 const int maxm=2e3+5; 7 const double eps=1e-5; 8 9 struct seg{ 10 double x,y1,y2; 11 int c; 12 bool operator