zoukankan      html  css  js  c++  java
  • POJ 1177 Picture [离散化+扫描线+线段树]

    http://poj.org/problem?id=1177
    给若干矩形,求被覆盖的区域的周长。

    y 坐标离散化后,按 x 坐标进行扫描。用线段树维护两个东西,当前竖线的叠加长度 len 和 条数 cnt 。 前一个用来计算竖直方向的周长部分,后一个用来计算水平方向的。
    left[node]right[node] 来记录每个结点左端和右端是否被覆盖,用来维护 cnt

    重叠的边也不能计算,这反应在对扫描线的排序上,两线重叠时入边应在出边之前。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using namespace std;
    
    #define CHD int lc = node<<1,rc = node<<1|1;
    #define MID int mid = (L+R)>>1;
    #define debug(x) cout<<"debug "<<x<<endl;
    #define rep(i,f,t) for(int i = (f),_end =(t); i <= _end; ++i)
    
    struct Node{
        int x;
        int y1,y2;
        int flag; //入边为1,出边为-1
        Node(int x,int y1,int y2,int f)
            :x(x),y1(y1),y2(y2),flag(f){
            }
        bool operator< (const Node &n2)const{
            if(x == n2.x)return flag > n2.flag;//入边在出边前
            return x < n2.x;
        }
    };
    vector<Node> line;
    vector<int> vs;
    const int maxn = 10005;
    
    struct sgt{
        int len[maxn<<2];
        int cnt[maxn<<2];
        int cov[maxn<<2];
        int left[maxn<<2];
        int right[maxn<<2];
    
        void maintain(int node,int L,int R){
            if(cov[node] > 0){
                len[node] = vs[R]-vs[L-1];
                cnt[node] = 1;
                left[node] = right[node] = 1;
            } else {
                if(L == R){
                    len[node] = 0;
                    cnt[node] = 0;
                    left[node] = right[node] = 0;
                }else{
                    CHD;
                    len[node] = len[lc]+len[rc];
                    cnt[node] = cnt[lc]+cnt[rc]-(left[rc]&right[lc]);
                    left[node] = left[lc];
                    right[node] = right[rc];
                }
            }
        }
        void update(int from,int to,int val,int node,int L,int R){
            if(from <= L && R <= to){
                cov[node] += val;
            } else {
                MID;CHD;
                if(from <= mid) update(from,to,val,lc,L,mid);
                else    maintain(lc,L,mid);
                if(to > mid) update(from,to,val,rc,mid+1,R);
                else    maintain(rc,mid+1,R);
            }
            maintain(node,L,R);
        }
    
        int solve(){
            int ans = 0,ans2 = 0;//竖直和水平方向的周长
            int n = vs.size()-1;
            int last = 0;
            rep(i,0,line.size()-1){
                int x = line[i].x;
                int f = line[i].y1+1;
                int t = line[i].y2;
                if(i > 0){
                    int tmp = cnt[1] * (x-line[i-1].x);
                    ans2 += tmp*2;
                }
                update(f,t,line[i].flag,1,1,n);
                ans += abs(last-len[1]);//竖直方向长度变化
                last = len[1];
            }
            return ans+ans2;
        }
    }tree;
    
    
    void pre(){
        sort(vs.begin(),vs.end());
        vs.erase(unique(vs.begin(),vs.end()),vs.end());
        rep(i,0,line.size()-1){
            line[i].y1 = lower_bound(vs.begin(),vs.end(),line[i].y1) - vs.begin();
            line[i].y2 = lower_bound(vs.begin(),vs.end(),line[i].y2) - vs.begin();
        }
        sort(line.begin(),line.end());
    }
    
    int main(){
        int n;
        scanf("%d",&n);
        if(n == 0){
            printf("0
    ");
            return 0;
        }
        line.reserve(n<<1);
        vs.reserve(n<<1);
        rep(i,1,n){
            int x1,y1,x2,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            vs.push_back(y1);
            vs.push_back(y2);
            line.push_back(Node(x1,y1,y2,1));
            line.push_back(Node(x2,y1,y2,-1));
        }
        pre();
        int ans = tree.solve();
        printf("%d
    ",ans);
        return 0;
    }
    

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    奶酪(NOIP2017 Day2 T1)
    图的遍历(某谷P3916)
    20154331 EXP9web安全基础实践
    20154331 EXP8 web基础
    20154331EXP7 网络欺诈
    20154331 Exp6 信息搜集与漏洞扫描
    Exp5 MSF基础应用
    Exp4 恶意代码分析
    Exp3 免杀原理与实践
    20154331黄芮EXP2 后门原理与实践
  • 原文地址:https://www.cnblogs.com/DSChan/p/4861973.html
Copyright © 2011-2022 走看看