这个线段树的作用其实是维护一组(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. DNS的工作原理及解析

    DNS协议是互联网核心协议之一.不管是上网浏览,还是编程开发,都需要了解一点它的知识. 一.什么是DNS? DNS( Domain Name System)是“域名系统”的英文缩写,是一种组织成域层次 ...

  2. Openwrt 安装软件到U盘或硬盘

    http://blog.licess.org/openwrt-install-software-to-udisk-harddisk/ 运行一个多月的DDNAS被结婚来玩的小孩给关了,于是趁机更新了一下 ...

  3. linux迁移至固态硬盘全过程

    自从台式机上用上固态硬盘后,就再也受不了笔记本上的5400转的机械硬盘了,所以这次又买了块固态硬盘打算装到笔记本上. 笔记本里装的是Ubuntu 14.04 + Win7双系统,Win7主要偶尔运行一 ...

  4. grep命令使用技巧

    grep如何实现全词查找例如:要查找name这个单词,反馈的查找结果不能包含namespace这样的模式,但是可以包含name()这样的模式,即要查找的单词两端不可以有其他的数字或者字母,但可以有空格 ...

  5. the first week study

    1.In 1989, a man named Guido create "python" as a kind of computer languages. And now we u ...

  6. PHP使用debug_backtrace方法跟踪代码调用

    在开发过程中,例如要修改别人开发的代码或调试出问题的代码,需要对代码流程一步步去跟踪,找到出问题的地方进行修改.如果有一个方法可以获取到某段代码是被哪个方法调用,并能一直回溯到最开始调用的地方(包括调 ...

  7. Codeforces 757 D. Felicity's Big Secret Revealed 状压DP

    D. Felicity's Big Secret Revealed   The gym leaders were fascinated by the evolutions which took pla ...

  8. scala wordcount kmeans

    scala wordcount   kmeans k-means算法的输入对象是d维向量空间的一些点,对一个d维向量的点集进行聚类. k-means聚类算法会将集合D划分成k个聚簇.

  9. CXF+Spring+Tomcat 案例

    多系统(异构系统)进行交互时,一种良好的方式便是调用Web Service,本示例基于Apache组织的CXF 环境:EclipseJDK6Tomcat6CXF2.6.1Spring3 示例项目结构图 ...

  10. webService和RMI

    1.请求: servlet:提供了请求/响应模式,是JAVA的一种规范,只能使用于java上,用来替代早期使用的难懂的CGI,是一种无状态的请求响应,客户端访问一个服务器的url,只需要发送简单的ht ...