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)
上一篇 2021年12月4日 下午6:00
下一篇 2021年12月4日 下午7:00


相关推荐

  • Zip伪加密 破解ZIP密码「建议收藏」

    Zip伪加密 破解ZIP密码「建议收藏」Zip伪加密 破解ZIP密码

    2022年4月21日
    65
  • windows server2012 AD域相关操作「建议收藏」

    windows server2012 AD域相关操作「建议收藏」AD域主要作用就是集中管理,限制域内用户或计算机的所有操作,主要管理公司员工,就像通讯录一样,还能管理了电脑,打印机等,权限管理,ADhelper可以实现WEB方式的AD域管理,方便、快捷。其余不懂得还是直接上例子其余自己科普。实操AD域VMA、VMB虚拟机配置为主辅域,域名为szpdc.com; VMA做为GC、SchemaMaster、DomainNamingMa…

    2022年5月17日
    395
  • arcgis python 教程-ArcGIS Python 入门到精通,视频教程下载

    arcgis python 教程-ArcGIS Python 入门到精通,视频教程下载课程介绍:本课程15章42个视频,基于ArcGIS10.2版本,涵盖了如何使用Python开发ArcGIS自定义工具,具体包括:编辑器的使用安装;列表函数使用;汉字乱码处理;游标(cursor)查询、更新和插入;几何图形生成和坐标导出;属性查询和空间查询;字段映射(FieldMappings)和值表(ValueTable)使用;拓扑检查和创建的拓扑处理;文件TXT、XLS和ArcGIS数据转换;使…

    2022年6月26日
    36
  • “折戟”中国市场后,Manus创始人发声,复盘经验教训

    “折戟”中国市场后,Manus创始人发声,复盘经验教训

    2026年3月15日
    2
  • SQL函数大全及示例汇总

    SQL函数大全及示例汇总这里写自定义目录标题概述 1 聚合函数 2 转换函数 3 日期函数 4 数字函数 5 字符串函数 6 系统函数 7 文本和图像函数概述 SQL 中包含以下七种类型的函数 聚合函数 返回汇总值 转型函数 将一种数据类型转换为另外一种 日期函数 处理日期和时间 数学函数 执行算术运算 字符串函数 对字符串 二进制数据或表达式执行操作 系统函数 从数据库返回在 SQLSERVER 中的值 对象或设置的特殊信

    2026年3月17日
    2
  • html错误(一) Stack Overflow at line:0 IE下解决方案

    html错误(一) Stack Overflow at line:0 IE下解决方案一今天用IE测试发现一个很奇葩的问题:代码没有什么问题,但是在浏览器中会自动弹出一个错误如: 二错误原因分析2.1  重定义了系统的触发事件名称作为自定义函数名如: onclick/onsubmit… 都是系统保留的事件名称,不允许作为重定义函数名称。2.2 出现死循环,都提示:Stackoverflowatline:0,如:在图片对象定

    2022年7月15日
    15

发表回复

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

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