SGU 319 Kalevich Strikes Back(线段树扫描线)

SGU 319 Kalevich Strikes Back(线段树扫描线)

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

题目大意:

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
*/

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/118539.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux嵌入式系统的缺点,arm嵌入式主板的优缺点

    嵌入式主板是嵌入在设备里面做控制、数据处理使用的CPU板,常见的有两类,即基于X86的嵌入式主板和基于RISC的ARM嵌入式主板。今天我们就来认识arm嵌入式主板,arm嵌入式主板就是一个嵌入在设备里面做控制、数据处理使用的CPU板。一般作为工控主板使用。ARM处理器是一种16/32位的嵌入式RISC微处理器,具有低成本、高性能、低功耗的特点。ARM9系列微处理器具有以下特点:支持32位ARM…

    2022年4月9日
    86
  • 霍尼韦尔与浙江石化扩大合作,助力中国最大石化项目进一步建设[通俗易懂]

    霍尼韦尔与浙江石化扩大合作,助力中国最大石化项目进一步建设[通俗易懂]霍尼韦尔在第二届中国国际进口博览会上宣布,浙江石油化工有限公司(以下称“浙江石化”)将在其位于浙江省舟山的炼化一体化二期项目采用霍尼韦尔一系列先进技术,包括工艺技术、催化剂、关键设备和控制自动化技术。舟山炼化一体化项目是中国国家经济最新发展规划中的数个大型石化产业基地之一。合作内容包括:霍尼韦尔UOPMD/ECMD塔盘,用于两套240万吨芳烃装置中的精馏和汽提环节,为客户提供出色的性能和经济效…

    2022年10月16日
    4
  • memwatch使用[通俗易懂]

    memwatch使用[通俗易懂]一、简介memwatch可以跟踪程序中的内存泄漏和错误,能检测双重释放(double-free)、错误释放(erroneousfree)、没有释放的内存(unfreedmemory)、溢出(Overflow)、下溢(Underflow)等。下载地址:http://www.linkdata.se/sourcecode/memwatch/解压后,得到源码memwa

    2022年7月13日
    21
  • keypad 按键响应流程解析「建议收藏」

    keypad 按键响应流程解析「建议收藏」一、keypad驱动,接收按键事件并将按键值转换为Linuxcode上发。二、如何一层层上传到Android系统的控件中。

    2022年5月20日
    47
  • mysql省市区递归查询_mysql 递归查询

    mysql省市区递归查询_mysql 递归查询1、创建表:DROPTABLEIFEXISTS`t_areainfo`;CREATETABLE`t_areainfo`(`id`int(11)NOT”AUTO_INCREMENT,`level`int(11)DEFAULT”,`name`varchar(255)DEFAULT”,`parentId`int(11)DEFAULT”,`status`i…

    2022年6月15日
    35
  • mysql中使用show table status 查看表信息

    mysql中使用show table status 查看表信息

    2021年10月14日
    44

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号