• 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
    ",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?'
    ':' ');
        }
        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
    */
    


  • 相关阅读:
    弹性盒子
    bzoj4237 稻草人
    bzoj2654 tree
    bzoj4813 [Cqoi2017]小Q的棋盘
    bzoj1014 [JSOI2008]火星人
    bzoj3242 [Noi2013]快餐店
    bzoj4025 二分图
    bzoj3237 [Ahoi2013]连通图
    bzoj3244 [Noi2013]树的计数
    bzoj2431 [HAOI2009]逆序对数列
  • 原文地址:https://www.cnblogs.com/yxwkf/p/3942735.html
Copyright © 2020-2023  润新知