zoukankan      html  css  js  c++  java
  • POJ2528线段树段更新逆序异或(广告牌)

    题意:
         可以这样理解,有一条直线,然后用n条线段去覆盖,最后问全部都覆盖完之后还有多少是没有被完全覆盖的。


    思路:

         一开始想的有点偏,想到起点排序,然后..失败了,原因是忘记了题目输入的顺序就是覆盖的顺序,后来突然想到了逆序,这个题目想到逆序也就差不多了,我们可以逆序处理,然后用异或操作去判断当前这段是否全部都被覆盖了,只要异或不是1,那么就是还有没覆盖的,那么答案++,更新这段,把这段全都覆盖上。


    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    
    #define N 20005
    #define lson l ,mid ,t << 1
    #define rson mid + 1 ,r ,t << 1 | 1
    
    using namespace std;
    
    typedef struct
    {
        int l ,r;
    }EDGE;
    
    EDGE E[N];
    int X[N*4];
    int mark[N*4];
    int num[N] ,numt[N];
    
    void PushUp(int t)
    {
        X[t] = X[t<<1] & X[t<<1|1];
        return ;
    }
    
    void PushDown(int t)
    {
        if(mark[t])
        {
            mark[t<<1] = mark[t<<1|1] = 1;
            X[t<<1] = X[t<<1|1] = 1;
            mark[t] = 0;
        }
        return ;
    }
    
    void BuidTree()
    {
        memset(X ,0 ,sizeof(X));
        memset(mark ,0 ,sizeof(mark));
        return ;
    }
    
    void Update(int l ,int r ,int t ,int a ,int b)
    {
        if(a <= l && b >= r)
        {
            X[t] = mark[t] = 1;
            return ;
        }
        PushDown(t);
        int mid = (l + r) >> 1;
        if(a <= mid) Update(lson ,a ,b);
        if(b > mid) Update(rson ,a ,b);
        PushUp(t);
    }
    
    int Query(int l ,int r ,int t ,int a ,int b)
    {
        if(a <= l && b >= r)
        return X[t];
        PushDown(t);
        int mid = (l + r) >> 1;
        int s1 = -1 ,s2 = -1;
        if(a <= mid) s1 = Query(lson ,a ,b);
        if(b > mid)  s2 = Query(rson ,a ,b);
        if(s1 == -1 && s2 == -1) return 0;
        if(s1 == -1) return s2;
        if(s2 == -1) return s1;
        return s1 & s2;
    }
    
    int Search2(int n ,int a)
    {
        int low = 1 ,up = n ,mid ,ans;
        while(low <= up)
        {
            mid = (low + up) >> 1;
            if(a >= num[mid])
            {
                ans = mid;
                low = mid + 1;
            }
            else up = mid - 1;
        }
        return ans;
    }
    
    int main ()
    {
        int n ,i ,Ans ,t ,id ,nn;
        scanf("%d" ,&t);
        while(t--)
        {
            scanf("%d" ,&n);
            for(id = 0 ,i = 1 ;i <= n ;i ++)
            {
                scanf("%d %d" ,&E[i].l ,&E[i].r);
                numt[++id] = E[i].l;
                numt[++id] = E[i].r;
            }
            sort(numt + 1 ,numt + id + 1);
            nn = 0;
            for(i = 1 ;i <= id ;i ++)
            if(i == 1 || numt[i] != numt[i-1])
            num[++nn] = numt[i];
            BuidTree();
            for(Ans = 0 ,i = n ;i >= 1 ;i --)
            {
                int l = Search2(nn ,E[i].l);
                int r = Search2(nn ,E[i].r);
                if(Query(1 ,nn ,1 ,l ,r)) continue;
                Ans ++;
                Update(1 ,nn ,1 ,l ,r);
            }
            printf("%d
    " ,Ans);
        }
        return 0;
    }
    
    
    
    
    
    


  • 相关阅读:
    linux命令:ls
    linux 进程线程拓展
    linux命令:find
    电动车充电器原理及带电路图维修
    kmalloc分配物理内存与高端内存映射--Linux内存管理(十八)
    Linux内核最新的连续内存分配器(CMA)——避免预留大块内存【转】
    alloc_page分配内存空间--Linux内存管理(十七)
    伙伴系统之避免碎片--Linux内存管理(十六)
    伙伴系统之伙伴系统概述--Linux内存管理(十五)
    USB初学(一)---USB-HID的初步认识【转】
  • 原文地址:https://www.cnblogs.com/csnd/p/12062382.html
Copyright © 2011-2022 走看看