zoukankan      html  css  js  c++  java
  • poj 2528 (线段树+离散化)

    poj 2528

    For each input data set print the number of visible posters after all the posters are placed. 

    The picture below illustrates the case of the sample input. 

    Sample Input

    1
    5
    1 4
    2 6
    8 10
    3 4
    7 10
    

    Sample Output

    4

    题意:贴报纸,可以互相覆盖,求最后能看见多少。

    数据很大,不离散会超出内存。将浪费的部分去掉,将出现过的所有点其映射到相距更近的点上。


    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    #define N 100005
    #define mod 258280327
    #define MIN 0
    #define MAX 1000001
    
    int l[N],r[N];
    int x[N];
    int has[10000005];
    
    struct node
    {
        int le,re;
        bool covered;
    } pnode[10*N];
    
    void build(int i,int l,int r)
    {
        pnode[i].le = l;
        pnode[i].re = r;
        pnode[i].covered = false;
        if(l == r)
            return;
    
        build(2 * i,l,(l+r)/2);
        build(2*i+1,(l+r)/2+1,r);
    }
    
    bool insert(int i,int l,int r,int a,int b)//是否可见
    {
        if(pnode[i].covered == true)//如果要找的已经被覆盖
            return false;
        if(l == a && r == b)
        {
            pnode[i].covered = true;
            return true;
        }
    
        bool ans;
        int mid = (l + r)>>1;
        if (mid >= b)
            ans = insert(i*2,l, mid,  a, b);
        else if (mid < a)
            ans = insert(i*2+1,mid+1, r, a, b);
        else
        {
            bool x1 = insert(i*2,l, mid, a, mid);
            bool x2 = insert(i*2+1,mid+1, r, mid+1, b);
            ans = x1 || x2;
        }
    
        if(pnode[i*2].covered == true && pnode[i*2+1].covered == true)
            pnode[i].covered = true;
        return ans;
    }
    
    
    
    
    int main()
    {
        int T,n,tot;
        scanf("%d",&T);
    
        while(T--)
        {
            scanf("%d",&n);
            tot = 0;
            for(int i = 1; i <= n; i++)
            {
                scanf("%d%d",&l[i],&r[i]);
                x[tot++] = l[i];
                x[tot++] = r[i];
            }
    
            sort(x,x+tot);
            tot = unique(x,x+tot)-x;
            int all=1;
            for(int i = 0;i < tot;i++)
            {
                has[x[i]] = all;
                if(i < tot - 1)
                {
                    if(x[i+1] - x[i] == 1)
                        all++;
                    else
                        all+=2;
                }
            }
    
            build(1,1,all);
            int num = 0;
    
            for(int i = n;i >=1;i--)
            {
                if(insert(1,1,all,has[l[i]],has[r[i]]))
                    num ++;
            }
    
            printf("%d
    ",num);
    
        }
        return 0;
    }
    

      

  • 相关阅读:
    获取有关控件的坐标
    Android PopupWindow的使用和分析
    Android RecyclerView 使用完全解析 体验艺术般的控件
    TextView中显示价格并且中间直接有一个横线
    Android Studio
    移动开发】Android中三种超实用的滑屏方式汇总(ViewPager、ViewFlipper、ViewFlow)
    Android中visibility属性VISIBLE、INVISIBLE、GONE的区别
    理解Java的IO流 2015年8月6日 21:30:38
    算法导论学习随笔——第七章 快速排序
    oj 1031 random permutation
  • 原文地址:https://www.cnblogs.com/Przz/p/5409777.html
Copyright © 2011-2022 走看看