这个线段树的作用其实是维护一组(1维 平面(?) 上的)线段覆盖的区域的总长度,支持加入/删除一条线段。

线段树只能维护整数下标,因此要离散化。

也可以理解为将每一条处理的线段分解为一些小线段,要求每一条要处理的线段都能这么分解

注意端点,线段树维护的是线段,而查询是端点,可能需要稍微变一下

具体的query方法好像类似标记永久化(?)

感觉不优美啊。。。想了一会并没有想到更好的方法。。。。

codevs:

错误记录:

1.打成unordered_map<int,int>

2.70、75行两个tlen误为len

3.要求保留两位小数

 #include<cstdio>
#include<algorithm>
#include<tr1/unordered_map>
using namespace std;
using namespace tr1;
struct Q
{
int x1,x2;double y1,y2,tx1,tx2;
}q[];
struct QQ
{
int l,r;double h;int fl;
friend bool operator<(const QQ &a,const QQ &b) {return a.h<b.h;}
}qq[];
double tt[];
unordered_map<double,int> ma;
int len,tlen;double ans;
int n;
namespace SegT
{
#define lc (num<<1)
#define rc (num<<1|1)
#define mid (l+((r-l)>>1))
//[l,r]表示点l到点r+1之间的线段
int cover[];double dat[];
int L,R,x;
void build(int l,int r,int num)
{
cover[num]=;dat[num]=;
if(l!=r) build(l,mid,lc),build(mid+,r,rc);
}
void addx(int l,int r,int num)
{
if(L<=l&&r<=R)
{
cover[num]+=x;
if(cover[num]) dat[num]=tt[r+]-tt[l];
else dat[num]=dat[lc]+dat[rc];
return;
}
if(L<=mid) addx(l,mid,lc);
if(mid<R) addx(mid+,r,rc);
if(cover[num]) dat[num]=tt[r+]-tt[l];
else dat[num]=dat[lc]+dat[rc];
}
#undef lc
#undef rc
#undef mid
}
int main()
{
int i;
while()
{
scanf("%d",&n);len=tlen=;ans=;ma.clear();
if(n==) break;
for(i=;i<=n;i++)
{
scanf("%lf%lf%lf%lf",&q[i].tx1,&q[i].y1,&q[i].tx2,&q[i].y2);
tt[++tlen]=q[i].tx1;tt[++tlen]=q[i].tx2;
}
sort(tt+,tt+tlen+);tlen=unique(tt+,tt+tlen+)-tt-;
for(i=;i<=tlen;i++) ma[tt[i]]=i;
for(i=;i<=n;i++) q[i].x1=ma[q[i].tx1],q[i].x2=ma[q[i].tx2]-;
for(i=;i<=n;i++)
{
qq[++len]=(QQ){q[i].x1,q[i].x2,q[i].y1,};
qq[++len]=(QQ){q[i].x1,q[i].x2,q[i].y2,-};
}
sort(qq+,qq+len+);SegT::build(,tlen-,);
for(i=;i<=len;i++)
{
ans+=SegT::dat[]*(qq[i].h-qq[i-].h);
SegT::L=qq[i].l;SegT::R=qq[i].r;SegT::x=qq[i].fl;
SegT::addx(,tlen-,);
}
printf("%.2lf\n",ans);
}
return ;
}

hdu

 #include<cstdio>
#include<algorithm>
#include<tr1/unordered_map>
using namespace std;
using namespace tr1;
struct Q
{
int x1,x2;double y1,y2,tx1,tx2;
}q[];
struct QQ
{
int l,r;double h;int fl;
friend bool operator<(const QQ &a,const QQ &b) {return a.h<b.h;}
}qq[];
double tt[];
unordered_map<double,int> ma;
int len,tlen;double ans;
int n;
namespace SegT
{
#define lc (num<<1)
#define rc (num<<1|1)
#define mid (l+((r-l)>>1))
//[l,r]表示点l到点r+1之间的线段
int cover[];double dat[];
int L,R,x;
void build(int l,int r,int num)
{
cover[num]=;dat[num]=;
if(l!=r) build(l,mid,lc),build(mid+,r,rc);
}
void addx(int l,int r,int num)
{
if(L<=l&&r<=R)
{
cover[num]+=x;
if(cover[num]) dat[num]=tt[r+]-tt[l];
else dat[num]=dat[lc]+dat[rc];
return;
}
if(L<=mid) addx(l,mid,lc);
if(mid<R) addx(mid+,r,rc);
if(cover[num]) dat[num]=tt[r+]-tt[l];
else dat[num]=dat[lc]+dat[rc];
}
#undef lc
#undef rc
#undef mid
}
int main()
{
int i,T=;
while()
{
scanf("%d",&n);len=tlen=;ans=;ma.clear();
if(n==) break;
for(i=;i<=n;i++)
{
scanf("%lf%lf%lf%lf",&q[i].tx1,&q[i].y1,&q[i].tx2,&q[i].y2);
tt[++tlen]=q[i].tx1;tt[++tlen]=q[i].tx2;
}
sort(tt+,tt+tlen+);tlen=unique(tt+,tt+tlen+)-tt-;
for(i=;i<=tlen;i++) ma[tt[i]]=i;
for(i=;i<=n;i++) q[i].x1=ma[q[i].tx1],q[i].x2=ma[q[i].tx2]-;
for(i=;i<=n;i++)
{
qq[++len]=(QQ){q[i].x1,q[i].x2,q[i].y1,};
qq[++len]=(QQ){q[i].x1,q[i].x2,q[i].y2,-};
}
sort(qq+,qq+len+);SegT::build(,tlen-,);
for(i=;i<=len;i++)
{
ans+=SegT::dat[]*(qq[i].h-qq[i-].h);
SegT::L=qq[i].l;SegT::R=qq[i].r;SegT::x=qq[i].fl;
SegT::addx(,tlen-,);
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n",++T,ans);
}
return ;
}

codevs 3044 矩形面积求并 || hdu 1542的更多相关文章

  1. codevs 3044 矩形面积求并

    3044 矩形面积求并   题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入描述 Input Description 可能有多组数据,读到n=0为止(不 ...

  2. poj1151==codevs 3044 矩形面积求并

    Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 21511   Accepted: 8110 Descrip ...

  3. codevs 3044 矩形面积求并 (扫描线)

    /* 之前一直偷懒离散化+暴力做着题 今天搞一下扫描线 自己按照线段树的一般写法写的有些问题 因为不用于以前的区间sum so 题解搬运者23333 Orz~ 去掉了打标记的过程 同时更新区间的时候先 ...

  4. codves 3044 矩形面积求并

    codves  3044 矩形面积求并  题目等级 : 钻石 Diamond 题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入描述 Input Desc ...

  5. 【题解】codevs 3044 矩形面积合并

    传送门 3044 矩形面积求并 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下 ...

  6. 3044 矩形面积求并 - Wikioi

    题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入描述 Input Description 可能有多组数据,读到n=0为止(不超过15组) 每组数据第一行 ...

  7. [Codevs] 矩形面积求并

    http://codevs.cn/problem/3044/ 线段树扫描线矩形面积求并 基本思路就是将每个矩形的长(平行于x轴的边)投影到线段树上 下边+1,上边-1: 然后根据线段树的权值和与相邻两 ...

  8. [codevs3044][POJ1151]矩形面积求并

    [codevs3044][POJ1151]矩形面积求并 试题描述 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入 可能有多组数据,读到n=0为止(不超过15组) 每组数据第一行一个数n ...

  9. 矩形面积求并(codevs 3044)

    题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入描述 Input Description 可能有多组数据,读到n=0为止(不超过15组) 每组数据第一行 ...

随机推荐

  1. Excel小tips - 如何设置表格输入数字后末尾自动添加%

    选中一列——鼠标右键——设置单元格格式——数字——自定义——0% 按照以上操作完成后,点击确定,就大功告成了.

  2. Jmeter参数Parameters和Body Data区别

    1.如图: 2.有文章说,Parameters是get的参数:Body Data是post的参数:get的参数存在于url中,post的参数存在于body中:   但是我使用jmeter3.3版本测试 ...

  3. 【Nginx】如何使用http配置

    处理http配置项可以分为下面4个步骤: 1)创建数据结构用于存储配置项对应的参数 2)设定配置项在nginx.conf中出现时的限制条件与回调方法 3)实现第2步中的回调方法,或者使用Nginx框架 ...

  4. SQL 约束(Constraints)

    SQL 约束(Constraints) SQL 约束(Constraints) SQL 约束用于规定表中的数据规则. 如果存在违反约束的数据行为,行为会被约束终止. 约束可以在创建表时规定(通过 CR ...

  5. 微信小程序之 Tabbar(底部选项卡)

    1.项目目录 2.在app.json里填写:tab个数范围2-5个 app.json { "pages": [ "pages/index/index", &qu ...

  6. 微信通过openID发送消息/后台post、get提交并接收数据 C# .NET 配置404,500等错误信息 连接字符串

    微信通过openID发送消息/后台post.get提交并接收数据   控制器:下面是post发送消息(微信不支持从前台发送数据,之前试过,报错,需要跨域,跨域的问题解决后还不行,最后发现之后后端提交 ...

  7. 使用Blender批量导出/转换模型

    2.4版本号的Blender API和2.5以上版本号的API有非常大的不同,这里仅仅是提供了思路和2.4版本号的导出方案. 先提供一个脚本,这个是由Blender调用的.用于转换Ogre的Mesh文 ...

  8. cmd下复制粘贴

    cmd下复制粘贴的快捷操作方式 工具/原料 系统cmd 步骤/方法 1 如右图,右键命令提示符窗口的标题栏,选择属性. 2 选择“编辑选项”里的“快速编辑模式”,并确定之: 3 在弹出的应用选择提示框 ...

  9. ubuntu中查看已安装软件包的方法

    ubuntu中查看已安装软件包的方法: 方法一:在新立得软件包管理器中,打到已安装,便可以看看有多少包被安装. 如果想把这些包的信息复制到一文件里,可用下面的方法. 方法二:在终端输入 sudo dp ...

  10. yummain.py install yum 不能运行的原因 yummain.py not found

    [root@akinlau ~] wget http://tel.mirrors.163.com/centos/6/os/x86_64/Packages/python-urlgrabber-3.9.1 ...