SGU 319. Kalevich Strikes Back (线段树)
319. Kalevich Strikes Back
Memory limit: 65536 kilobytes
output: standard
And yet again the Berland community can see that talent is always multi-sided. The talent is always seeking new ways of self-expression. This time genius Kalevich amazed everybody with his new painting "Rectangular Frames". The masterpiece is full of impenetrable meaning and hidden themes.
Narrow black rectangular frames are drawn on a white rectangular canvas. No two frames have a common point. Sides of each frame are parallel to the sides of the canvas.
The painting is very big and the reduced replica cannot pass the idea of the original drawing. That's why Kalevich requested that the simplified versions of the masterpiece should be used as replicas. The simplified version is the sequence of the areas of all facets of the original. A facet is a connected enclosed white area within the painting. The areas in the sequence should be written in the non-decreasing order.
The first line of the input contains an integer N (1 ≤ N ≤ 60000) — the number of the frames on the drawing. The second line contains integer numbers W and H (1 ≤ W, H ≤ 108).
Let's introduce the Cartesian coordinate system in such a way that the left bottom corner of the canvas has (0, 0) coordinate and the right top corner has the (W, H) coordinate. The sides of the canvas are parallel to the axes.
The following N lines contain the description of the frames. Each description is composed of the coordinates of the two opposite corners of the corresponding frame x1, y1, x2, y2(1 ≤ x1, x2 < W; 1 ≤ y1, y2 < H; x1 != x2, y1 != y2). All coordinates are integers. No two frames have a common point.
Write the desired sequence to the output.
sample input |
sample output |
1 |
1 8 |
矩形不相交,可能会内含。
使用线段树的扫描线,搞出保含关系,然后dfs一遍。
/* ***********************************************
Author :kuangbin
Created Time :2014/5/1 16:10:22
File Name :E:\2014ACM\专题学习\数据结构\线段树\SGU319.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int MAXN = ;
struct Node
{
int l,r;
int ll,rr;//实际的左右区间
int c;//覆盖标记,懒惰标记
}segTree[MAXN*];
int x[MAXN];
struct Line
{
int x1,x2,y;
int id;
Line(){}
Line(int _x1,int _x2,int _y,int _id)
{
x1 = _x1;
x2 = _x2;
y = _y;
id = _id;
}
}line[MAXN];
bool cmp(Line a,Line b)
{
return a.y < b.y;
}
void push_down(int r)
{
if(segTree[r].l + == segTree[r].r)return;
if(segTree[r].c != -)
{
segTree[r<<].c = segTree[(r<<)|].c = segTree[r].c;
segTree[r].c = -;
}
}
void build(int i,int l,int r)
{
segTree[i].l = l;
segTree[i].r = r;
segTree[i].ll = x[l];
segTree[i].rr = x[r];
segTree[i].c = ;
if(l+ == r)return;
int mid = (l+r)/;
build(i<<,l,mid);
build((i<<)|,mid,r);
}
int pre[MAXN];
void Update(int i,Line e)
{
if(segTree[i].ll == e.x1 && segTree[i].rr == e.x2)
{
if(e.id > )
segTree[i].c = e.id;
else segTree[i].c = pre[-e.id];
return;
}
push_down(i);
if(e.x2 <= segTree[i<<].rr)Update(i<<,e);
else if(e.x1 >= segTree[(i<<)|].ll)Update((i<<)|,e);
else
{
Line tmp = e;
tmp.x2 = segTree[i<<].rr;
Update(i<<,tmp);
tmp = e;
tmp.x1 = segTree[(i<<)|].ll;
Update((i<<)|,tmp);
}
}
int query(int i,Line e)
{
if(segTree[i].c != -)
return segTree[i].c;
if(e.x2 <= segTree[i<<].rr)return query(i<<,e);
else if(e.x1 >= segTree[(i<<)|].ll)return query((i<<)|,e);
else
{
e.x2 = segTree[i<<].rr;
return query(i<<,e);
}
}
long long area[MAXN];
vector<int>vec[MAXN];
void dfs(int u)
{
int sz = vec[u].size();
for(int i = ;i < sz;i++)
{
int v = vec[u][i];
area[u] -= area[v];
dfs(v);
}
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;
int w,h;
while(scanf("%d",&n) == )
{
scanf("%d%d",&w,&h);
area[] = (long long)w*h;
int x1,x2,y1,y2;
int tot = ;
for(int i = ;i <= n;i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(x1 > x2)swap(x1,x2);
if(y1 > y2)swap(y1,y2);
area[i] = (long long)(x2-x1)*(y2-y1);
line[tot] = Line(x1,x2,y1,i);
x[tot++] = x1;
line[tot] = Line(x1,x2,y2,-i);
x[tot++] = x2;
}
sort(x,x+tot);
tot = unique(x,x+tot) - x;
build(,,tot-);
sort(line,line+*n,cmp);
for(int i = ;i <= n;i++)
vec[i].clear();
for(int i = ;i < *n;i++)
{
if(line[i].id > )
{
pre[line[i].id] = query(,line[i]);
vec[pre[line[i].id]].push_back(line[i].id);
}
Update(,line[i]);
}
dfs();
sort(area,area+n+);
for(int i = ;i <= n;i++)
{
printf("%I64d",area[i]);
if(i < n)printf(" ");
else printf("\n");
}
}
return ;
}
SGU 319. Kalevich Strikes Back (线段树)的更多相关文章
- SGU 319 Kalevich Strikes Back(线段树扫描线)
题目大意: n个矩形,将一个大矩形分成 n+1 块.矩形之间不重合,可是包括.求这n+1个矩形的面积 思路分析: 用线段树记录他们之间的父子关系.然后dfs 计算面积. 当给出的矩形上边的时候,就要记 ...
- SGU 531. Bonnie and Clyde 线段树
531. Bonnie and Clyde 题目连接: http://acm.sgu.ru/problem.php?contest=0&problem=531 Description Bonn ...
- SGU 311. Ice-cream Tycoon(线段树)
311. Ice-cream Tycoon Time limit per test: 0.5 second(s)Memory limit: 65536 kilobytes input: standar ...
- SGU 180 Inversions(离散化 + 线段树求逆序对)
题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=180 解题报告:一个裸的求逆序对的题,离散化+线段树,也可以用离散化+树状数组.因为 ...
- SGU - 311 Ice-cream Tycoon(线段树)
Description You've recently started an ice-cream business in a local school. During a day you have m ...
- BestCoder Round #56 1002 Clarke and problem 1003 Clarke and puzzle (dp,二维bit或线段树)
今天第二次做BC,不习惯hdu的oj,CE过2次... 1002 Clarke and problem 和Codeforces Round #319 (Div. 2) B Modulo Sum思路差不 ...
- bzoj3932--可持久化线段树
题目大意: 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第 ...
- codevs 1082 线段树练习 3(区间维护)
codevs 1082 线段树练习 3 时间限制: 3 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...
- codevs 1576 最长上升子序列的线段树优化
题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...
随机推荐
- IEnumerable 和 IQueryable 区别
IQueryable继承自IEnumerable,所以对于数据遍历来说,它们没有区别. 但是IQueryable的优势是它有表达式树,所有对于IQueryable的过滤,排序等操作,都会先缓存到表达式 ...
- powerdsigner Association Multiplicity
这一篇來告诉一个不容易分辨的关系图式:Association(结合)的各种類型,除了了解它的涵义 外,也让各位可以看图說故事,知道它背后所要表达的意义. Association结合 Associati ...
- SQL总结(二)连表查询
---恢复内容开始--- SQL总结(二)连表查询 连接查询包括合并.内连接.外连接和交叉连接,如果涉及多表查询,了解这些连接的特点很重要. 只有真正了解它们之间的区别,才能正确使用. 1.Union ...
- 【java】之读取InputStream流
如这个文件 @Test public void test01() throws Exception{ InputStream in=new FileInputStream("c://test ...
- MSSQL 判断临时表是否存在
方法一: if exists (select * from tempdb.dbo.sysobjects where id = object_id(N'tempdb..#tempcitys') and ...
- (C#) 求两个数组的交集
基本上在面试的时候,会具体到两个int数组,或string数组.具体也就是讨论算法. 首先需要的是和面试的人确认题目的含义,并非直接答题. 然后,可以提出自己的想法,首先最快的是用linq { Lis ...
- [HTML] CSS3 圆角
使用 CSS3 border-radius 属性,你可以给任何元素制作 "圆角". CSS3 border-radius 属性 使用 CSS3 border-radius 属性,你 ...
- HashTable,HashSet与Dictionary
1.HashTable 哈希表(HashTable)表示键/值对的集合.在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现 ...
- 使用php添加定时任务
1. php执行外部命令的函数: system(),exec(),passthru() 注意点: 1.调用的路径,相对路径有时候不是很靠谱. sys ...
- VS2010+VMWare8+VisualDDK1.5.6 创建并调试你的第一个驱动程序 - 完全教程
本文描述了如何使用Visual Studio+VMMare+VisualDDK来创建.编译和调试你的第一个驱动程序.本文提供在开发和调试工具的环境下详细的操作步骤,而无需太多的关心这些环境背后所做的事 ...