zoukankan      html  css  js  c++  java
  • POJ-1177-Picture(线段树+扫描线+离散化)[矩形周长并]

    题解:http://www.notonlysuccess.com/index.php/segment-tree-complete/

    题意:求矩形周长

    分析:与面积不同的地方是还要记录竖的边有几个(numseg记录)也就是[记录线段树被覆盖的区间有多少个],并且当边界重合的时候需要合并(用lbd和rbd表示边界来辅助)
    线段树操作:update:区间增减 query:直接取根节点的值

    // File Name: 1177.cpp
    // Author: Zlbing
    // Created Time: 2013/7/20 19:53:20
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define LL long long
    #define REP(i,r,n) for(int i=r;i<=n;i++)
    #define RREP(i,n,r) for(int i=n;i>=r;i--)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    
    const int MAXN=1e4+100;
    struct seg{
        int x1,x2,y;
        int flag;
        bool operator <(const seg& rsh)const
        {
            if(y==rsh.y)return flag>rsh.flag;
            else return y<rsh.y;
        }
    }G[MAXN];
    int hash[MAXN];
    
    int col[MAXN<<2];
    int sum[MAXN<<2];
    bool lbd[MAXN<<2],rbd[MAXN<<2];
    int numseg[MAXN<<2];
    void pushup(int rt,int l,int r)
    {
        if(col[rt]){
            lbd[rt]=1,rbd[rt]=1;
            numseg[rt]=2;
            sum[rt]=hash[r+1]-hash[l];
        }
        else if(l==r){
            sum[rt]=lbd[rt]=rbd[rt]=numseg[rt]=0;
        }
        else{
            sum[rt]=sum[rt<<1]+sum[rt<<1|1];
            lbd[rt]=lbd[rt<<1];
            rbd[rt]=rbd[rt<<1|1];
            numseg[rt]=numseg[rt<<1]+numseg[rt<<1|1];
            if(lbd[rt<<1|1]&&rbd[rt<<1])numseg[rt]-=2;//两条线重合
        }
    }
    void update(int L,int R,int flag,int l,int r,int rt)
    {
        if(L<=l&&R>=r)
        {
            col[rt]+=flag;
            pushup(rt,l,r);
            return;
        }
        int m=(l+r)>>1;
        if(L<=m)update(L,R,flag,lson);
        if(R>m)update(L,R,flag,rson);
        pushup(rt,l,r);
    }
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            int a,b,c,d;
            int xlen=0;
            REP(i,1,n)
            {
                scanf("%d%d%d%d",&a,&b,&c,&d);
                G[xlen].x1=a,G[xlen].x2=c,G[xlen].y=b,G[xlen].flag=1;
                hash[xlen]=a;
                xlen++;
                G[xlen].x1=a,G[xlen].x2=c,G[xlen].y=d,G[xlen].flag=-1;
                hash[xlen]=c;
                xlen++;
            }
            sort(G,G+xlen);
            sort(hash,hash+xlen);
            int len=unique(hash,hash+xlen)-hash;
            int ans=0;
            int last=0;
            for(int i=0;i<xlen;i++)
            {
                int x1=lower_bound(hash,hash+len,G[i].x1)-hash;
                int x2=lower_bound(hash,hash+len,G[i].x2)-hash-1;
                update(x1,x2,G[i].flag,0,len-1,1);
                ans+=numseg[1]*(G[i+1].y-G[i].y);
                ans+=abs(sum[1]-last);
                last=sum[1];
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    Android Studio复制项目作为一个新的工程
    7-(基础入门篇)关于STM32底层程序使用说明
    6-(基础入门篇)学会编译lua固件,固件的合成
    5-(基础入门篇)学会刷Wi-Fi模块固件(刷LUA版本固件)
    STM32嵌入LUA开发(控制小灯闪耀)
    1-添加自己的Lua执行函数(ESP8266-SDK开发(lua版本))
    android 权限动态申请
    Android应用更新-自动检测版本及自动升级
    Android中AsyncTask的使用
    关于TCP和MQTT之间的转换
  • 原文地址:https://www.cnblogs.com/arbitrary/p/3203084.html
Copyright © 2011-2022 走看看