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组) 每组数据第一行 ...
随机推荐
- 如何在不允许联网的环境下使用Maven开发
前言:Maven的运行机理是:Maven核心组件先去本地的.m2目录下的库中去寻找依赖或者插件,如果本地库里没有,如果配置了私服则上私服去下载依赖或者插件,如果私服上没有,则上中央服务等Maven服务 ...
- 分享codeigniter框架,在zend studio 环境下的代码提示
一.到github下载相关文件 https://github.com/Stunt/Codeigniter-autocomplete 二.把文件放到application/config中 代码提示就出来 ...
- DosBox 报错 this program requires dosxnt.exe to be in your path
也就是少了dosxnt.exe文件,能够上网搜索下载,把dosxnt 拷贝到你挂截文件夹下就能够执行 Dosxnt文件下载
- Linux程序设计(搭建开发环境--curses)
看官们.咱们今天要说的内容.是前面内容的一点小补充,详细的内容是:安装curses开发包.以搭建 开发环境.闲话休说,言归正转. 我们在前面说过搭建开发环境的内容,主要说了开发环境中的GCC和VIM, ...
- hdu 3183 A Magic Lamp 贪心
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm& ...
- ubuntu下spring环境搭建
一.安装JDK 下载官网:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 部署: ...
- Android:内存控制及OOM处理
1. OOM(内存溢出)和Memory Leak(内存泄露)有什么关系? OOM可能是因为Memory Leak,也可能是你的应用本身就比较耗内存(比如图片浏览型的).所以,出现OOM不一定是Me ...
- Django的各种初识
1,django项目的各个文件的介绍 1.1>项目的根目录:是各个子文件的根目录,在各个文件相互导入文件的时候使用 1.2>配置文件:为django的各个文件配置相关的各种默认配置 1.3 ...
- Hbase权限配置以及使用手册
1.Hbase权限控制简介 Hbase的权限控制是通过AccessController Coprocessor协处理器框架实现的,可实现对用户的RWXCA的权限控制. 2.配置 配置hbase-sit ...
- shutdown的几种方式,shutdown abort的一些弊端有哪些
1.shutdown normal 正常方式关闭数据库. 2.shutdown immediate 立即方式关闭数据库. 在SVRMGRL中执行shutdown immedia ...