codevs 3044 矩形面积求并 || hdu 1542
这个线段树的作用其实是维护一组(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的更多相关文章
- codevs 3044 矩形面积求并
3044 矩形面积求并 题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入描述 Input Description 可能有多组数据,读到n=0为止(不 ...
- poj1151==codevs 3044 矩形面积求并
Atlantis Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 21511 Accepted: 8110 Descrip ...
- codevs 3044 矩形面积求并 (扫描线)
/* 之前一直偷懒离散化+暴力做着题 今天搞一下扫描线 自己按照线段树的一般写法写的有些问题 因为不用于以前的区间sum so 题解搬运者23333 Orz~ 去掉了打标记的过程 同时更新区间的时候先 ...
- codves 3044 矩形面积求并
codves 3044 矩形面积求并 题目等级 : 钻石 Diamond 题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入描述 Input Desc ...
- 【题解】codevs 3044 矩形面积合并
传送门 3044 矩形面积求并 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下 ...
- 3044 矩形面积求并 - Wikioi
题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入描述 Input Description 可能有多组数据,读到n=0为止(不超过15组) 每组数据第一行 ...
- [Codevs] 矩形面积求并
http://codevs.cn/problem/3044/ 线段树扫描线矩形面积求并 基本思路就是将每个矩形的长(平行于x轴的边)投影到线段树上 下边+1,上边-1: 然后根据线段树的权值和与相邻两 ...
- [codevs3044][POJ1151]矩形面积求并
[codevs3044][POJ1151]矩形面积求并 试题描述 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入 可能有多组数据,读到n=0为止(不超过15组) 每组数据第一行一个数n ...
- 矩形面积求并(codevs 3044)
题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入描述 Input Description 可能有多组数据,读到n=0为止(不超过15组) 每组数据第一行 ...
随机推荐
- delphi 修改文件夹名和文件名
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Form ...
- 支付宝移动支付之IOSApp调用支付宝钱包
近期客户提出要开发一个IOS上的app作为訪问他们站点的途径之中的一个.为什么说之中的一个呢.因为眼下PC和Mobile这两个站眼下都已经上线了. 所以问题就简单了,我们仅仅须要把mobile站UI改 ...
- 关于rman duplicate 一些比較重要的知识点--系列三
FYI: http://docs.oracle.com/cd/E11882_01/backup.112/e10643/rcmsynta020.htm#RCMRF126 rman duplicate d ...
- 将Python打印的内容进行高亮的输出
将打印的内容进行高亮的显示 内容: 格式: echo "\033[字背景颜色;字体颜色m字符串\033[0m" 例如: "\033[41;36m something he ...
- udhcp源码详解(二)--转
定义的数据结构对于C程序的重要性,不言而喻.面向对象设计的程序是一个个对象的集合,而面向过程语言设计的程序则是数据结构与算法的集合. 下面来分析的是dhcp server中的定义结构体: 1).在pa ...
- 安装BIRT Chart Engine的时候,提示Cannot complete the install because one or more required items could not be
http://wiki.eclipse.org/BIRT_Update_Site_URL 每个eclipse对应的BIRT版本 help-install new software: http://do ...
- HDFS集中式缓存管理(Centralized Cache Management)
Hadoop从2.3.0版本号開始支持HDFS缓存机制,HDFS同意用户将一部分文件夹或文件缓存在HDFS其中.NameNode会通知拥有相应块的DataNodes将其缓存在DataNode的内存其中 ...
- ip地址的唯一性是如何保证的
连接ISP网络时,运行商就分配了一个ip地址,所以,ip地址是运营商指定的. 账户只是控制是否可以接入而已,只要是插上网线,就已经动态分配了ip地址.
- linux环境下oracle静默安装
一.安装环境 1.linux版本:redhat6.3_x86_64 2.oracle版本:Oracle Database 11g Enterprise Edition Release 11.2.0.3 ...
- Java-Runoob-高级教程-实例-字符串:13. Java 实例 - 字符串格式化
ylbtech-Java-Runoob-高级教程-实例-字符串:13. Java 实例 - 字符串格式化 1.返回顶部 1. Java 实例 - 字符串格式化 Java 实例 以下实例演示了通过 f ...