题目描述

N(N<5000) 张矩形的海报,照片和其他同样形状的图片贴在墙上。它们的边都是垂直的或水平的。每个矩形可以部分或者全部覆盖其他矩形。所有的矩形组成的集合的轮廓称为周长。写一个程序计算周长。

所有矩形的顶点坐标均为整数。所有的坐标都在 [-10000,10000] 的范围内,并且任何一个矩形面积都为整数。结果的值可能需要 32 位有符号整数表示。

输入

第1行: N,张贴在墙上的矩形的数目。 第 2..N+1行 接下来的N行中,每行都有两个点的坐标,分别是矩形的左下角坐标和右上角坐标。每一个坐标由 X 坐标和 Y 坐标组成。

输出

只有一行,为一个非负整数,表示输入数据中所有矩形集合的轮廓长度。

样例输入

7
-15 0 5 10
-5 8 20 25
15 -4 24 14
0 -6 16 4
2 15 10 22
30 10 36 20
34 0 40 16

样例输出

228

题解:

线段树+扫描线

对于每条线段,分横竖考虑,排序,坐标第一关键字,左右第2关键字

对于矩形左边线段,先统计这条线段区域0的个数,在把线段树中这条线段覆盖的区域+1,右边反过来

一定要记得右端点-1(因为题目给的是点,实际上是区间)

例如1,3。其实只覆盖2个区间(1,2;2,3)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct data1{
int l,r,k,p;
}x[],y[];
struct data2{
int x,s,l,r,la;
}tree[];
int n;
bool cmp(data1 a,data1 b)
{
if(a.k==b.k)return a.p>b.p;
return a.k<b.k;
}
void down(int x)
{
tree[x*].x+=tree[x].la;
tree[x*].la+=tree[x].la;
tree[x*+].x+=tree[x].la;
tree[x*+].la+=tree[x].la;
tree[x].la=;
}
void up(int x)
{
tree[x].x=min(tree[x*].x,tree[x*+].x);
if(tree[x*].x==tree[x*+].x)tree[x].s=tree[x*].s+tree[x*+].s;
if(tree[x*].x<tree[x*+].x)tree[x].s=tree[x*].s;
if(tree[x*].x>tree[x*+].x)tree[x].s=tree[x*+].s;
}
void init(int x,int l,int r)
{
tree[x].l=l;tree[x].r=r;tree[x].la=;tree[x].x=;
if(l==r){tree[x].s=;return;}
init(x*,l,(l+r)/);init(x*+,(l+r)/+,r);
up(x);
}
void add(int x,int l,int r,int k)
{
if(tree[x].l==l&&tree[x].r==r){tree[x].x+=k;tree[x].la+=k;return;}
down(x);
int mid=(tree[x].l+tree[x].r)/;
if(r<=mid)add(x*,l,r,k);
else if(l>mid)add(x*+,l,r,k);
else {add(x*,l,mid,k);add(x*+,mid+,r,k);}
up(x);
}
void query(int x,int l,int r,int &ansx,int &anss)
{
if(tree[x].l==l&&tree[x].r==r)
{
if(ansx==tree[x].x)anss+=tree[x].s;
if(tree[x].x<ansx)anss=tree[x].s;
ansx=min(ansx,tree[x].x);return;
}
down(x);
int mid=(tree[x].l+tree[x].r)/;
if(r<=mid)query(x*,l,r,ansx,anss);
else if(l>mid)query(x*+,l,r,ansx,anss);
else {query(x*,l,mid,ansx,anss);query(x*+,mid+,r,ansx,anss);}
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
int _x1,_y1,_x2,_y2;
scanf("%d%d%d%d",&_x1,&_y1,&_x2,&_y2);
_x1+=;_x2+=;_y1+=;_y2+=;
y[i*-].l=_x1;y[i*-].r=_x2-;y[i*-].k=_y1;y[i*-].p=;
y[i*].l=_x1;y[i*].r=_x2-;y[i*].k=_y2;y[i*].p=-;
x[i*-].l=_y1;x[i*-].r=_y2-;x[i*-].k=_x1;x[i*-].p=;
x[i*].l=_y1;x[i*].r=_y2-;x[i*].k=_x2;x[i*].p=-;
}
n*=;int ans=;
sort(x+,x+n+,cmp);sort(y+,y+n+,cmp);
init(,,);
for(int i=;i<=n;i++)
{
if(x[i].p==-)add(,x[i].l,x[i].r,-);
int anss=,ansx=;query(,x[i].l,x[i].r,ansx,anss);
if(x[i].p==)add(,x[i].l,x[i].r,);
if(ansx==)ans+=anss;
}
init(,,);
for(int i=;i<=n;i++)
{
if(y[i].p==-)add(,y[i].l,y[i].r,-);
int anss=,ansx=;query(,y[i].l,y[i].r,ansx,anss);
if(y[i].p==)add(,y[i].l,y[i].r,);
if(ansx==)ans+=anss;
}
cout<<ans;return ;
}

[9018_1963][IOI_1998]Picture的更多相关文章

  1. 基于Picture Library创建的图片文档库中的上传多个文件功能(upload multiple files)报错怎么解决?

    复现过程 首先,我创建了一个基于Picture Library的图片文档库,名字是 Pic Lib 创建完毕后,我点击它的Upload 下拉菜单,点击Upload Picture按钮 在弹出的对话框中 ...

  2. MFC Picture控件加载图片

    CStatic *pPic = (CStatic*)GetDlgItem(IDC_PICTURE); CBitmap bitmap; bitmap.LoadBitmapW(IDB_BITMAP2); ...

  3. [POJ1177]Picture

    [POJ1177]Picture 试题描述 A number of rectangular posters, photographs and other pictures of the same sh ...

  4. USACO 5.5 Picture(周长并)

    POJ最近做过的原题. /* ID: cuizhe LANG: C++ TASK: picture */ #include <cstdio> #include <cstring> ...

  5. 彩色照片转换为黑白照片(Color image converted to black and white picture)

    This blog will be talking about the color image converted to black and white picture. The project st ...

  6. HDU 1828 Picture(线段树扫描线求周长)

    Picture Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  7. don't forget the bigger picture

    Imagine a circle that contains all of human knowledge: By the time you finish elementary school, you ...

  8. A Complete Guide to the <Picture> Element

    If you’ve ever struggled building responsive websites, this post is for you. It’s part of a series o ...

  9. HDUOJ-----(1162)Eddy's picture(最小生成树)

    Eddy's picture Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

随机推荐

  1. A Country on Wheels【车轮上的国家】

    A Country on Wheels As cultural symbols go, the American  car is quite young. 作为文化象征的美国汽车还相当年轻. The ...

  2. __builtin_popcount() 函数

    详解 该函数的主要作用是计算一个数字的二进制中有多少个1,返回值就是其中1的个数. 它使用一张基于表的方法来进行位搜索,因此这个操作的执行效率很高 此处举一题 P1582 倒水 #include &l ...

  3. 笔记-ORM-sqlalchemy

    笔记-ORM-sqlalchemy 1.      ORM 1.1.    ORM框架简介 对象-关系映射(Object/Relation Mapping,简称ORM),是随着面向对象的软件开发方法发 ...

  4. 课后题2.87&2.86

    课后题2.86&2.87 单纯就是想加点分第十章的题目都被做过了就做下第二章的,正好复习一下前面学的知识,第二章给我剩下的题目也不多了,我就挑了这个题目. 2.86 考虑一个基于IEEE浮点格 ...

  5. 小白日记1:kali环境Wpscan渗透Wordpress

    一.什么是Wpscan?什么是Wordpres? 1.Wpscan WPScan是一款针对wordpress的安全扫描软件:可以扫描出wordpress的版本,主题,插件,后台用户以及爆破后台用户密码 ...

  6. Toolbar中menu菜单文字颜色的修改

    Toolbar菜单中menu当中我们大多数都使用图片来按钮,可是有些时候我们也会直接使用文字,文字的颜色如何修改呢. 其实很简单,我们只要修改styles.xml文件中,添加一句 <item n ...

  7. 两个category方法相同调用哪个

    Category扩展,它是对一个类进行功能的扩展.在项目的开发过程中,在不断的迭代开发过程中,我们的类也不可避免的要根据需求来增加新的功能,而这个时候很多的人可能会新建一个子类,然后在子类中去增加我们 ...

  8. C#正则表达式引发的CPU跑高问题以及解决方法

    3月23日(周日)下午16:30左右,博客园主站负载均衡中的2台Web服务器CPU玩起了爬楼梯的游戏(见上图),一直爬到了接近100%.发现这个状况后,我们立即将这2台阿里云临时磁盘云服务器从负载均衡 ...

  9. python3 打印九九乘法口诀表

    for i in range(1, 10): for j in range(1, i+1): # print(f'{i}×{j}={i*j}', end='\t') print('%d×%d=%d' ...

  10. UIAutomator2、Appium、Robotium搭建环境与框架对比

    UIAutomator2.Appium.Robotium搭建环境与框架对比 一.框架介绍 Appium 特点 appium 是一个自动化测试开源工具,支持 iOS 平台和 Android 平台上的原生 ...