zoukankan      html  css  js  c++  java
  • poj 2528(区间改动+离散化)

    题意:有一个黑板上贴海报。给出每一个海报在黑板上的覆盖区间为l r,问最后多少个海报是可见的。


    题解:由于l r取值到1e7,肯定是要离散化的,但普通的离散化会出问题。比方[1,10],[1,4],[6,10]普通得到答案是2,但事实上是3。改进的离散化方法假设两个数字相差大于1,就在中间补一个数字。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int N = 10005;
    int n, l[N], r[N], a[N << 3], tree[N << 4], vis[N], res;
    
    void pushdown(int k) {
        if (tree[k] != -1) {
            tree[k * 2] = tree[k * 2 + 1] = tree[k];
            tree[k] = -1;
        }
    }
    
    void modify(int k, int left, int right, int l1, int r1, int x) {
         if (l1 <= left && right <= r1) {
             tree[k] = x;
             return;
         }
         pushdown(k);
         int mid = (left + right) / 2;
         if (mid >= l1)
            modify(k * 2, left, mid, l1, r1, x);
        if (mid < r1)
            modify(k * 2 + 1, mid + 1, right, l1, r1, x);
    }
    
    void query(int k, int left, int right) {
        if (left == right) {
            if (!vis[tree[k]]) {
                res++;
                vis[tree[k]] = 1;
           }
           return;
        }
        pushdown(k);
        int mid = (left + right) / 2;
        query(k * 2, left, mid);
        query(k * 2 + 1, mid + 1, right);
    }
    
    int main() {
        int t;
        scanf ("%d", &t);
        while (t--) {
            memset(tree, -1, sizeof(tree));
            memset(vis, 0, sizeof(vis));
            int cnt = 0;
            scanf("%d", &n);
            for (int i = 1; i <= n; i++) {
                 scanf ("%d%d", &l[i], &r[i]);
                 a[++cnt] = l[i];
                 a[++cnt] = r[i];
            }
            sort(a + 1, a + 1 + cnt);
            cnt = unique(a + 1, a + 1 + cnt) - (a + 1);
            int cnt2 = cnt;
            for (int i = 2; i <= cnt; i++)
                if (a[i] - a[i - 1] > 1)
                    a[++cnt2] = a[i] - 1;
            cnt = cnt2;
            sort(a + 1, a + 1 + cnt);
            for (int i = 1; i <= n; i++) {
                int l1 = lower_bound(a + 1, a + 1 + cnt, l[i]) - a;
                int r1 = lower_bound(a + 1, a + 1 + cnt, r[i]) - a;
                modify(1, 1, cnt, l1, r1, i);
            }
        res = 0;
        query(1, 1, cnt);
            printf("%d
    ", res);
        }
        return 0;
    }
  • 相关阅读:
    C# 字符串转换值类型
    C#判断字符串为空
    c#转义字符
    python各种类型的转换
    mysql创建新用户及新用户不能本地登陆的问题
    数据探索的方法
    使用requests爬取猫眼电影TOP100榜单
    Python中的正则表达式教程
    Anaconda多版本Python管理以及TensorFlow版本的选择安装
    Xshell访问虚拟机内Linux
  • 原文地址:https://www.cnblogs.com/cxchanpin/p/7224563.html
Copyright © 2011-2022 走看看