• UVA 11983 Weird Advertisement --线段树求矩形问题


    题意:给出n个矩形,求矩形中被覆盖K次以上的面积的和。

    解法:整体与求矩形面积并差不多,不过在更新pushup改变len的时候,要有一层循环,来更新tree[rt].len[i],其中tree[rt].len[i]表示覆盖次数大于等于i的线段长度,以便求面积,最后只要每次都用tree[1].len[K]来算面积即可。

    代码:

    #include <iostream>
    #include <cmath>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #define ll long long
    using namespace std;
    #define N 30007
    
    struct node
    {
        int cov;
        ll len[12];
    }tree[8*N];
    
    struct Line
    {
        ll y1,y2,x;
        int cov;
    }line[2*N];
    ll yy[2*N];
    int K;
    
    int cmp(Line ka,Line kb)
    {
        return ka.x < kb.x;
    }
    
    void addLine(ll x1,ll x2,ll y1,ll y2,int &m)
    {
        line[m].x = x1,line[m].y1 = y1,line[m].y2 = y2,line[m].cov = 1,yy[m++] = y1;
        line[m].x = x2,line[m].y1 = y1,line[m].y2 = y2,line[m].cov = -1,yy[m++] = y2;
    }
    
    int bsearch(int l,int r,ll x)
    {
        while(l <= r)
        {
            int mid = (l+r)/2;
            if(yy[mid] == x)
                return mid;
            if(yy[mid] < x)
                l = mid+1;
            else
                r = mid-1;
        }
        return l;
    }
    
    void build(int l,int r,int rt)
    {
        tree[rt].cov = 0;
        memset(tree[rt].len,0,sizeof(tree[rt].len));
        if(l+1 == r) return;
        int mid = (l+r)/2;
        build(l,mid,2*rt);
        build(mid,r,2*rt+1);
    }
    
    void pushup(int l,int r,int rt)
    {
        int cov = tree[rt].cov;
        for(int i=0;i<=K;i++)
        {
            if(cov >= i)
                tree[rt].len[i] = yy[r]-yy[l];
            else if(l+1 == r)
                tree[rt].len[i] = 0;
            else
                tree[rt].len[i] = tree[2*rt].len[i-cov] + tree[2*rt+1].len[i-cov];
        }
    }
    
    void update(int l,int r,int aa,int bb,int cov,int rt)
    {
        if(aa <= l && bb >= r)
        {
            tree[rt].cov += cov;
            pushup(l,r,rt);
            return;
        }
        if(l+1 == r) return;
        int mid = (l+r)/2;
        if(aa <= mid)
            update(l,mid,aa,bb,cov,2*rt);
        if(bb > mid)
            update(mid,r,aa,bb,cov,2*rt+1);
        pushup(l,r,rt);
    }
    
    int main()
    {
        int t,cs = 1,n,m,i,j;
        ll x1,x2,y1,y2;
        yy[0] = 0;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&K);
            m = 1;
            for(i=0;i<n;i++)
            {
                scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
                x2++,y2++;
                addLine(x1,x2,y1,y2,m);
            }
            if(K > n)
            {
                printf("Case %d: %d
    ",cs++,0);
                continue;
            }
            m--;
            sort(yy+1,yy+m+1);
            int cnt = 2;
            for(i=2;i<=m;i++)
            {
                if(yy[i] != yy[i-1])
                    yy[cnt++] = yy[i];
            }
            cnt--;
            build(1,cnt,1);
            sort(line+1,line+m+1,cmp);
            ll ans = 0;
            for(i=1;i<m;i++)
            {
                int L = bsearch(1,cnt,line[i].y1);
                int R = bsearch(1,cnt,line[i].y2);
                update(1,cnt,L,R,line[i].cov,1);
                ans += tree[1].len[K]*(line[i+1].x-line[i].x);
            }
            printf("Case %d: %lld
    ",cs++,ans);
        }
        return 0;
    }
    View Code

    线段树求矩形面积交也可用类似方法,令K = 2即可

  • 相关阅读:
    先做人,再做事
    当ligerui的grid出现固定列与非固定列不在同一水平线上时,改怎么处理
    权限设计的idea
    ligerUI问题
    在程序出现问题,当找不到错误时,第一时间用try ,catch包括起来
    当页面是本地页面时,通过ajax访问tomcat里的action,传递的参数在action里并不能识别
    好句子
    js Uncaught TypeError: undefined is not a function
    Photoshop学习笔记(一)
    microsoft project 出现不能保存为xls文件时可以按照如下方法解决
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3940974.html
Copyright © 2020-2023  润新知