这个线段树的作用其实是维护一组(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. JVM监控工具:jps、jstat、jinfo、jmap、jhat、jstack使用介绍

    转载:http://outofmemory.cn/java/jvm/jvm-tools-jps-jstat-jinfo-jmap-jhat-jstack 一.jps(JVM Process Statu ...

  2. VMware虚拟机上安装linux和克隆

    虚拟机上安装好一台linux 系统后.为了高速搭建hadoop集群.须要再安装几个linux系统,比較笨的办法能够又一次用ios 镜像文件进行安装.可是又一次安装须要又一次配置一些信息并且安装时间比較 ...

  3. SqlServer 经常使用分页方法总结

    SqlServer 经常使用分页方法总结 以下演示样例总结了,SqlServer数据库 经常使用分页方法,仅供学习參考 A. 使用 RowNumber 和 Between And 组合分页: /*** ...

  4. Django创建数据表

    Django中创建表. 用的django项目自带的sqlite数据库,创建完毕后将表注冊到jdango.admin,就能够在浏览器在管理了. 在django项目的models.py文件里: from  ...

  5. 实现@using{}代码块

    前几天,我要写个插件,放在asp.net mvc的view上.这需要写一些扩展HtmlHelper功能的方法.这些方法的一个参数是一段javascript代码. 假如这个参数类型是字符型,当然很简单了 ...

  6. MFC项目实战(1)文件管理器--界面设计篇

    1.创建项目 文件管理器是一个基于对话框的应用程序.首先新建一个“MFC应用程序”类型的项目,然后输入新建项目的名称“FileMng”,并指定该项目保存的位置,单击“确定”按钮,如图所示. 在弹出的“ ...

  7. RJ45接口定义及网线线序

    RJ45接口定义 常见的RJ45接口有两类:用于以太网网卡.路由器以太网接口等的DTE类型,还有用于交换机等的DCE类型. DTE我们可以称做“数据终端设备”,DCE我们可以称做“数据通信设备”.从某 ...

  8. I.MX6 mkuserimg.sh 使用

    /*********************************************************************** * I.MX6 mkuserimg.sh 使用 * 说 ...

  9. excel+requests管理测试用例接口自动化框架

    背景: 某项目有多个接口,之前使用的unittest框架来管理测试用例,将每个接口的用例封装成一个py文件,接口有数据或者字段变动后,需要去每个py文件中找出变动的接口测试用例,维护起来不方便,为了便 ...

  10. 13_传智播客iOS视频教程_OC程序的编译链接

    C程序的编译.链接.执行怎么来的?在.C文件里面写上符合C语言部分的源代码.OC也是一样的.记住:OC程序的后缀名是.m. 为什么要链接?第一个.o的目标文件里面它启动不了.因为它没有启动代码我们要加 ...