zoukankan      html  css  js  c++  java
  • 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即可

  • 相关阅读:
    使用gzip优化web应用(filter实现)
    在Spring、Hibernate中使用Ehcache缓存(2)
    Ehcache 整合Spring 使用页面、对象缓存(1)
    ehcache-----在spring和hibernate下管理ehcache和query cache
    使用Spring MVC构建REST风格WEB应用
    开涛spring3(12.4)
    开涛spring3(12.3)
    LLE局部线性嵌入算法
    图像固定条纹干扰
    多尺度字典学习超分辨率——相关中文文献
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3940974.html
Copyright © 2011-2022 走看看