POJ1389 给定n个整数点矩形,求面积并。

显然ans必然是整数。

记录若干个事件,每个矩形的左边的竖边记为开始,右边的竖边记为结束。

进行坐标离散化后用线段树维护每个竖的区间, 就可以快速积分了。

#include<stdio.h>
#include<stdlib.h>
#include<cstring>
#include<math.h>
#include<algorithm>
#include<vector>
using namespace std; const int maxn=100005;
struct Rectangle
{
int x1,y1,x2,y2;
}; struct Event
{
int x,y1,y2,add;
}; struct IntervalTreeNode
{
int count,total;
}; int n; Rectangle rect[maxn];
Event evt[maxn<<1];
IntervalTreeNode tree[(maxn+10)<<2];
int id[maxn<<1];
bool cmp(const Event &a,const Event &b)
{
if(a.x<b.x)return true;
return false;
} void up(int i,int lb,int rb)
{
tree[i].total=tree[i<<1].total+tree[(i<<1)+1].total;
if(tree[i].count)tree[i].total=id[rb]-id[lb];
} void ins(int i,int lb,int rb,int a,int b,int k)
{
if(a==lb&&b==rb){
tree[i].count+=k;
up(i,lb,rb);
return ;
}
int med=(lb+rb)>>1;
if(b<=med) ins(i<<1,lb,med,a,b,k);
else if(a>=med)ins((i<<1)+1,med,rb,a,b,k);
else{
ins(i<<1,lb,med,a,med,k);
ins((i<<1)+1,med,rb,med,b,k);
}
up(i,lb,rb);
} long long area()
{
for(int i=0;i<n;i++){
id[i]=rect[i].y1;
id[i+n]=rect[i].y2;
}
sort(id,id+2*n);
for(int i=0;i<2*n;i++){
rect[i].y1=lower_bound(id,id+2*n,rect[i].y1)-id;
rect[i].y2=lower_bound(id,id+2*n,rect[i].y2)-id;//坐标离散化
}
for(int i=0;i<n;i++){
evt[i].add=1;
evt[i+n].add=-1;
evt[i].x=rect[i].x1;
evt[i+n].x=rect[i].x2;
evt[i].y1=evt[i+n].y1=rect[i].y1;
evt[i].y2=evt[i+n].y2=rect[i].y2;
}
sort(evt,evt+n*2,cmp);
long long int ans=0;
for(int i=0;i<2*n;i++){
if(i>0&&evt[i].x>evt[i-1].x){
ans+=(long long )(evt[i].x-evt[i-1].x)*tree[1].total;
}
ins(1,0,2*n-1,evt[i].y1,evt[i].y2,evt[i].add);
}
return ans;
} int main()
{freopen("t.txt","r",stdin);
while(true)
{
n=0;
scanf("%d%d%d%d",&rect[0].x1,&rect[0].y1,&rect[0].x2,&rect[0].y2);
if(rect[0].x1==-1)return -1;
while(++n)
{
scanf("%d%d%d%d",&rect[n].x1,&rect[n].y1,&rect[n].x2,&rect[n].y2);
if(rect[n].x1==-1)break;
}
printf("%I64d\n",area());
}
return 0;
}

  

POJ1389 Area of Simple Polygons 线段树的更多相关文章

  1. POJ1389:Area of Simple Polygons——扫描线线段树题解+全套代码注释

    http://poj.org/problem?id=1389 题面描述在二维xy平面中有N,1 <= N <= 1,000个矩形.矩形的四边是水平或垂直线段.矩形由左下角和右上角的点定义. ...

  2. 【POJ 1389】Area of Simple Polygons(线段树+扫描线,矩形并面积)

    离散化后,[1,10]=[1,3]+[6,10]就丢了[4,5]这一段了. 因为更新[3,6]时,它只更新到[3,3],[6,6]. 要么在相差大于1的两点间加入一个值,要么就让左右端点为l,r的线段 ...

  3. POJ 1389 Area of Simple Polygons 扫描线+线段树面积并

    ---恢复内容开始--- LINK 题意:同POJ1151 思路: /** @Date : 2017-07-19 13:24:45 * @FileName: POJ 1389 线段树+扫描线+面积并 ...

  4. Area of Simple Polygons

    poj1389:http://poj.org/problem?id=1389 题意:求矩形面积的并题解:扫描线加线段树 同poj1389 #include<iostream> #inclu ...

  5. Codeforces Round #312 (Div. 2) E. A Simple Task 线段树

    E. A Simple Task 题目连接: http://www.codeforces.com/contest/558/problem/E Description This task is very ...

  6. Codeforces Round #312 (Div. 2) E. A Simple Task 线段树+计数排序

    题目链接: http://codeforces.com/problemset/problem/558/E E. A Simple Task time limit per test5 secondsme ...

  7. CodeForces 588E A Simple Task(线段树)

    This task is very simple. Given a string S of length n and q queries each query is on the format i j ...

  8. POJ Area of Simple Polygons 扫描线

    这个题lba等神犇说可以不用离散化,但是我就是要用. 题干: Description There are N, <= N <= , rectangles -D xy-plane. The ...

  9. Codeforces Round #312 (Div. 2) E. A Simple Task 线段树 延时标记

    E. A Simple Task time limit per test5 seconds memory limit per test512 megabytes inputstandard input ...

随机推荐

  1. assert.notDeepStrictEqual()详解

    assert.notDeepStrictEqual(actual, expected[, message]) 深度地严格不相等比较测试,与 assert.deepStrictEqual() 相反. c ...

  2. SQL-Redis使用详细教程

    一.Redis基础部分: 1.redis介绍与安装比mysql快10倍以上 *****************redis适用场合**************** 1.取最新N个数据的操作 2.排行榜应 ...

  3. SpringBoot第十六篇:自定义starter

    作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/11058502.html 版权声明:本文为博主原创文章,转载请附上博文链接! 前言   这一段时间 ...

  4. spring+orm框架的兼容问题

    Springframework和Hibernate版本对应关系 org.springframework 3.0.x对应org.hibernate4.0.x版本 org.springframework ...

  5. c/c++ 位域的概念

    位域 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一种数 ...

  6. POJ——T 2728 Desert King

    http://poj.org/problem?id=2728 Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 27191   ...

  7. Ubuntu 16.04硬盘有坏道,开机显示blk_update_request:I/0 error

    可以尝试以下方式解决: 1.检查坏道(效果明显,但是比较慢,检查出来并没有什么用,只是知道有坏块) sudo badblocks -s -v -o /root/bb.log /dev/sda1 2.快 ...

  8. 保持WCF服务端与客户端的长连接

    背景 客户端与服务端使用WCF建立连接后:1.可能长时间不对话(调用服务操作):2.客户端的网络不稳定. 为服务端与客户端两边都写“心跳检测”代码?不愿意. 解决 设置inactivityTimeou ...

  9. SQL server 2008 添加,删除字段

    添加,刪除字段 如果要在数据表中添加一个字段,应该如何表示呢?下面就为您介绍表添加字段的SQL语句的写法,希望可以让您对SQL语句有更深的认识. 通用式: alter table [表名] add [ ...

  10. WIN10中使用Hyper-V 配置虚拟机宿主机互ping

    在Windows10  Hyper-V 中安装 Linux (Ubuntu16.04)虚拟机无法 ping 通宿主机,宿主机可以ping通虚拟机. 这种情况下关闭 Windows 防火墙就能ping通 ...