zoukankan      html  css  js  c++  java
  • poj 2528 Mayor's posters(线段树)

    题目链接:http://poj.org/problem?id=2528

    思路分析:线段树处理区间覆盖问题,也可以看做每次给一段区间染不同的颜色,最后求在整段区间上含有的所有颜色种类数;

    注意由于区间太大,所以需要离散化;

    区间更新:对于线段树的每个结点,标记颜色,初始时没有颜色,标记为0;当更新时,使用延迟标记,需要标记传递到子节点;

    区间查询:使用深度优先查询线段树,当某个子节点的颜色不为0时,即停止深度优先搜索,并在map中查询是否已经记录该段区间的颜色;

    代码如下:

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    typedef struct { int x, y; }Pos;
    
    const int MAX_N = 10000 + 100;
    const int MAX_M = 10000000 + 100;
    int hash_val[MAX_M];
    int set[20 * MAX_N], arr[8 * MAX_N];
    int map[10 * MAX_N];
    Pos position[8 * MAX_N];
    int ans;
    
    void PushDown(int o)
    {
        int lc = 2 * o, rc = 2 * o + 1;
        if (set[o] != 0)
        {
            set[lc] = set[rc] = set[o];
            set[o] = 0;
        }
    }
    
    void Updata(int o, int l, int r, int color, int ql, int qr)
    {
        if (ql <= l && r <= qr)
            set[o] = color;
        else
        {
            int mid = (l + r) / 2;
            PushDown(o);
            if (ql <= mid)
                Updata(2 * o, l, mid, color, ql, qr);
            if (mid < qr)
                Updata(2 * o + 1, mid + 1, r, color, ql, qr);
        }
    }
    
    void Query(int o, int l, int r)
    {
        if (set[o] != 0)
        {
            if (map[set[o]] == 0)
            {
                map[set[o]] = 1;
                ans++;
            }
        }
        else if (l < r)
        {
            int mid = (l + r) / 2;
    
            Query(2 * o, l, mid);
            Query(2 * o + 1, mid + 1, r);
        }
    }
    
    int main()
    {
        int case_times, num;
        int min_len, max_len;
    
        scanf("%d", &case_times);
        while (case_times--)
        {
            memset(set, 0, sizeof(set));
            memset(map, 0, sizeof(map));
            memset(hash_val, 0, sizeof(hash_val));
    
            scanf("%d", &num);
            for (int i = 0; i < num; ++i)
            {
                scanf("%d %d", &arr[2 * i], &arr[2 * i + 1]);
                position[i].x = arr[2 * i];
                position[i].y = arr[2 * i + 1];
            }
            sort(arr, &arr[2 * num]);
            for (int i = 0; i < 2 * num; ++i)
            {
                if (i == 0)
                    hash_val[arr[i]] = 1;
                else if (arr[i] == arr[i - 1])
                    hash_val[arr[i]] = hash_val[arr[i - 1]];
                else if (arr[i] == arr[i - 1] + 1)
                    hash_val[arr[i]] = hash_val[arr[i - 1]] + 1;
                else
                    hash_val[arr[i]] = hash_val[arr[i - 1]] + 2;
            }
            min_len = 1;
            max_len = hash_val[arr[2 * num - 1]];
            for (int i = 0; i < num; ++i)
            {
                int ql = hash_val[position[i].x];
                int qr = hash_val[position[i].y];
                Updata(1, min_len, max_len, i + 1, ql, qr);
            }
            ans = 0;
            Query(1, min_len, max_len);
            printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    MapReduce1.x与MapReduce2.x差异
    刷题60—排序数组
    刷题59— 圆圈中最后剩下的数字
    刷题58—地图分析
    刷题57—单词的压缩编码
    刷题56—卡牌分组
    刷题55—车的可用捕获量
    刷题54—三维形体的表面积
    刷题53—按摩师
    刷题52—链表的中间结点
  • 原文地址:https://www.cnblogs.com/tallisHe/p/4567764.html
Copyright © 2011-2022 走看看