题目大意:

n个矩形,将一个大矩形分成 n+1 块。矩形之间不重合,可是包括。求这n+1个矩形的面积

思路分析:

用线段树记录他们之间的父子关系。然后dfs 计算面积。

当给出的矩形上边的时候,就要记录到该矩形的父亲去。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
#define maxn 70010 using namespace std;
typedef long long LL; int cov[maxn<<2];
LL area[maxn<<1];
int W,H; struct node
{
int s,e,h,type;
bool operator < (const node &cmp)const
{
return h<cmp.h;
}
}scline[maxn<<1]; struct foo
{
int s,e,h;
}sqr[maxn<<2]; int x[maxn<<1];
int pre[maxn<<1]; void pushdown(int num)
{
if(cov[num]!=-1){
cov[num<<1]=cov[num<<1|1]=cov[num];
cov[num]=-1;
}
}
void build(int num,int s,int e)
{
cov[num]=0;
if(s==e)return;
int mid=(s+e)>>1;
build(lson);
build(rson);
} void update(int num,int s,int e,int l,int r,int val)
{
if(l<=s && r>=e)
{
if(val<0)cov[num]=pre[abs(val)];
else cov[num]=val;
return;
}
pushdown(num);
int mid=(s+e)>>1;
if(l<=mid)update(lson,l,r,val);
if(r>mid)update(rson,l,r,val);
} int PRE;
int query(int num,int s,int e,int l,int r)
{ if(cov[num]!=-1)
{
return cov[num];
}
pushdown(num);
int mid=(s+e)>>1;
if(r<=mid)return query(lson,l,r);
else if(l>mid)return query(rson,l,r);
else return query(lson,l,mid);
} int head[maxn<<1];
int next[maxn<<1];
int to[maxn<<1];
int tot;
void add(int a,int b)
{
next[tot]=head[a];
head[a]=tot;
to[tot]=b;
tot++;
}
LL getarea(int index)
{
return (LL)sqr[index].h*(LL)(sqr[index].e-sqr[index].s);
}
void dfs(int x)
{
for(int s=head[x];s!=0;s=next[s])
{
area[x]-=getarea(to[s]);
dfs(to[s]);
}
} int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
tot=1; memset(pre,0,sizeof pre); scanf("%d%d",&W,&H);
area[0]=(LL)W*(LL)H;
sqr[0].s=0;sqr[0].e=W;sqr[0].h=H;
for(int i=1;i<=n;i++)
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2); if(x1>x2)swap(x1,x2);
if(y1>y2)swap(y1,y2);
sqr[i].s=x1;sqr[i].e=x2;sqr[i].h=y2-y1; scline[2*i-1].s=x1;
scline[2*i-1].e=x2;
scline[2*i-1].h=y1;
scline[2*i-1].type=i;
x[2*i-1]=x1; scline[2*i].s=x1;
scline[2*i].e=x2;
scline[2*i].h=y2;
scline[2*i].type=-i;
x[2*i]=x2;
} x[2*n+1]=0;
x[2*n+2]=W; for(int i=1;i<=n;i++)
area[i]=getarea(i); sort(x+1,x+2*n+3);
int m=unique(x+1,x+2*n+3)-(x+1)-1; build(1,0,m); sort(scline+1,scline+2*n+1);
memset(head,0,sizeof head);
tot=1;
for(int i=1;i<=2*n;i++)
{
int l=lower_bound(x+1,x+m+1,scline[i].s)-(x+1);
int r=lower_bound(x+1,x+m+1,scline[i].e)-(x+1); if(scline[i].type>0)
{
pre[scline[i].type]=query(1,0,m,l,r);
printf("%d %d\n",scline[i].type,pre[scline[i].type]);
add(pre[scline[i].type],scline[i].type); }
update(1,0,m,l,r,scline[i].type);
} dfs(0);
sort(area,area+n+1); for(int i=0;i<=n;i++)
printf("%lld%c",area[i],i==n?'\n':' ');
}
return 0;
}
/*
2
5 5
1 1 4 4
2 2 3 3 4
10 10
1 1 5 5
2 2 3 4
6 1 9 9
7 2 8 3 4
10 10
1 1 9 6
2 2 5 5
2 7 8 9
3 6 5 7
*/

SGU 319 Kalevich Strikes Back(线段树扫描线)的更多相关文章

  1. SGU 319. Kalevich Strikes Back (线段树)

    319. Kalevich Strikes Back Time limit per test: 0.5 second(s)Memory limit: 65536 kilobytes input: st ...

  2. 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)

    D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

  3. Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)

    题目链接:http://codeforces.com/contest/522/problem/D 题目大意:  给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...

  4. 【POJ-2482】Stars in your window 线段树 + 扫描线

    Stars in Your Window Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11706   Accepted:  ...

  5. HDU 4419 Colourful Rectangle --离散化+线段树扫描线

    题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何 ...

  6. BZOJ-3228 棋盘控制 线段树+扫描线+鬼畜毒瘤

    3228: [Sdoi2008]棋盘控制 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 23 Solved: 9 [Submit][Status][D ...

  7. BZOJ-3225 立方体覆盖 线段树+扫描线+乱搞

    看数据范围像是个暴力,而且理论复杂度似乎可行,然后被卡了两个点...然后来了个乱搞的线段树+扫描线.. 3225: [Sdoi2008]立方体覆盖 Time Limit: 2 Sec Memory L ...

  8. hdu 5091(线段树+扫描线)

    上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...

  9. POJ1151+线段树+扫描线

    /* 线段树+扫描线+离散化 求多个矩形的面积 */ #include<stdio.h> #include<string.h> #include<stdlib.h> ...

随机推荐

  1. Moutain Tai notes

    rest 40shaxian 18 drumsticks  13零食 11.5+21车费5门票62大衣10面14 > 194.5 notes :::: 岗位职责:1.基于Drupal系统的产品功 ...

  2. poj 2274 The Race 最小堆

    题目链接 题目大意: 给n个小车, 每个小车有一个初始位置x和初始速度v, 保证x1 < x2..... <xn. 0<v<100. 然后问你一共会发生多少次超车, 以及前10 ...

  3. poj 3378 Crazy Thairs dp+线段树+大数

    题目链接 题目大意: 给出n个数, 让你求出有多少个5元组满足 i < j < k < l < m并且ai < aj < ak < al < am 我们 ...

  4. UIKit之浅析UIButton

    UIButton * button =[[UIButton alloc]init]; button.backgroundColor=[UIColor redColor]; [button setTit ...

  5. VIM+qmake编译示例程序HelloQt出错问题的解决(文件名一定要使用.cpp,否则就会默认使用gcc编译,当然通不过)

    之前看到很多初学Qt的Linux友们在使用qmake编译第一个HelloQt或者HelloWorld程序时报错,并且始终找不到原因. 前几天我也遇到了同样的问题,我用的是<精通Qt4编程> ...

  6. mysql binlog 混合模式 出现的基于sql的数据不一致,主要是now()这类函数导致

  7. 一步一步学android之布局管理器——RelativeLayout

    今天开始学习RelativeLayout(相对布局),相对布局在平时布局的时候用的较多,因为Android适配方面的原因.相对布局可以控制组件摆放的位置(放在任一组件的上下左右等位置),下面来看看类的 ...

  8. Android之单击返回键两次退出

    private static Boolean isExit = false;        private static Boolean hasTask = false;        Timer t ...

  9. C# 文件帮助类

    using System; using System.Data; using System.Configuration; using System.Linq; using System.Web; us ...

  10. asp.net软件测试学习

    ormaping类是,将数据操作封装起来的一种数据操作方法,在测试的时候,如果说,insert之后对obj对象赋值赋值,每个属性应该对应自己的objDataRow["REGISTERID&q ...