zoukankan      html  css  js  c++  java
  • POJ 2528 Mayor's posters 贴海报 线段树 区间更新

    注意离散化!!!线段树的叶子结点代表的是一段!!!

    给出下面两个简单的例子应该能体现普通离散化的缺陷:
    1-10 1-4 5-10
    1-10 1-4 6-10

    普通离散化算出来的结果都会是2,但是第二组样例结果是3

    如果相邻数字间距大于1的话,在其中加上任意一个数字,比如加成[1,2,3,6,7,10],然后再做线段树就好了.

    线段树功能:update 成段更新,query 查询整个线段树

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    using namespace std;
    
    const int MAXN = 20010;
    int p[MAXN], mp[MAXN], pp[MAXN];
    int pst[MAXN<<4], ans;
    bool flag[MAXN];
    
    bool cmp(int A, int B)
    {
        return p[A] < p[B];
    }
    
    void push_down(int rt)
    {
        if(pst[rt] == 0) return;
        pst[rt<<1] = pst[rt<<1|1] = pst[rt];
        pst[rt] = 0;
    }
    
    void update(int L, int R, int c, int l, int r, int rt)
    {
        if(L <= l && r <= R)
        {
            pst[rt] = c;
            return;
        }
        push_down(rt);
        int m = (l + r) >> 1;
        if(m >= L) update(L, R, c, lson);
        if(m < R) update(L, R, c, rson);
    }
    
    void query(int l, int r, int rt)
    {
        if(pst[rt] > 0) //只有大于0才有海报
        {
            if(!flag[pst[rt]]) ans++;
            flag[pst[rt]] = 1;
            return;
        }
        if(l == r) return;
        push_down(rt);
        int m = (l + r) >> 1;
        query(lson);
        query(rson);
    }
    
    int main()
    {
    //    freopen("in.txt", "r", stdin);
        int T, n;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d", &n);
            for(int i=0; i<n; i++)
            {
                scanf("%d%d", &p[i<<1], &p[i<<1|1]);
                mp[i<<1] = i<<1;
                mp[i<<1|1] = i<<1|1;
            }
            sort(mp, mp+2*n, cmp);
            pp[mp[0]] = 1;
            int N = 1;
            for(int i=1; i<2*n; i++)    //离散化
            {
                if(p[mp[i]] == p[mp[i-1]])
                    pp[mp[i]] = N;
                else if(p[mp[i]] - p[mp[i-1]] > 1)  //大于1的插一个数
                {
                    N += 2;
                    pp[mp[i]] = N;
                }
                else pp[mp[i]] = ++N;
            }
            memset(pst, 0, sizeof(pst));
            for(int i=0; i<n; i++)
                update(pp[i<<1], pp[i<<1|1], i+1, 1, N, 1);
            memset(flag, 0, sizeof(flag));
            ans = 0;
            query(1, N, 1);
            printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    redis 报错随笔
    ElasticSearch restful实操 随笔
    phantomjs
    Linux环境安装安装NodeJS v10.16.3
    huawei 策略路由随笔
    eleasticsearch 安装-随笔
    cmake编译安装mysql
    postgres主从配置
    postgresql数据库部署
    redis环境部署
  • 原文地址:https://www.cnblogs.com/pach/p/7442620.html
Copyright © 2011-2022 走看看