• kuangbin_SegTree D (POJ 2528)


    讲道理我之前暂时跳过染色的题是因为总觉得有什么很高端的算法来query

    直到我做了F题(ZOJ 1610)才发现就是个暴力统计.....也对 也就几万个长度单位而已....

    F就不po上来了 选了有点难度的D题 需要用到离散化

    单纯的离散化又会碰到后染色覆盖前染色的 所以要在每两个差距大于1的位置之间插入一个位置

    以上思路参考了 http://blog.csdn.net/non_cease/article/details/7383736 但是原po的有点小错 混过了POJ的数据但是确实是错的...

    就是说底色可能会被不小心算进去 所以统计的时候要忽略底色

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define INF 0x3f3f3f3f
    #define mem(str,x) memset(str,(x),sizeof(str))  
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    using namespace std;
    typedef long long LL;
    
    const int MAXN = 10005;
    int n, hash[MAXN<<3], col[MAXN<<4];
    int ans, li[MAXN], ri[MAXN];
    bool vis[MAXN];
    
    inline void push_down(int rt){
        if(~col[rt]){
            col[rt<<1] = col[rt<<1|1] = col[rt];
            col[rt] = -1;
        }
    }
    
    void update(int L, int R, int c, int l, int r, int rt)
    {
        if(L <= l && R >= r){
            col[rt] = c;
            //printf("%d - %d : %d
    ", l, r, c);
            return;
        }
        
        push_down(rt);
        int m = (l + r) >> 1;
        if(L <= m) update(L, R, c, lson);
        if(R > m) update(L, R, c, rson);
    }
    
    void query(int l, int r, int rt)
    {
        if(l == r){
            if(!vis[col[rt]] && ~col[rt]){
                //printf("%d at %d
    ", col[rt], l);
                ans++;
                vis[col[rt]] = true;
            }
            return;
        }
        
        push_down(rt);
        int m = (l + r) >> 1;
        query(lson);
        query(rson);
    }
    
    int binary_search(int l, int r, int c)
    {
        int m;
        while(l <= r){
            m = (l + r) >> 1;
            if(hash[m] == c) return m;
            else if(hash[m] > c) r = m - 1;
            else l = m + 1;
        }
        return -1;
    }
    
    int main()
    {
        int t;
        scanf("%d", &t);
        while(t--){
            mem(col, -1);
            mem(vis, false);
            scanf("%d", &n);
            int nn = 0, mm = 1;
            for(int i = 1; i <= n; i++){
                scanf("%d%d", &li[i], &ri[i]);
                hash[++nn] = li[i];
                hash[++nn] = ri[i];
            }
            sort(hash+1, hash+1+nn);
            //去除重复数据 
            for(int i = 2; i <= nn; i++){
                if(hash[i] != hash[i-1]) hash[++mm] = hash[i];
            }
            //在相距超过1的点之间插入一个点防止覆盖 
            for(int i = mm; i > 1; i--){
                if(hash[i] - hash[i-1] > 1) hash[++mm] = hash[i] - 1;
            }
            sort(hash+1, hash+1+mm);
            //离散化构造线段树 
            for(int i = 1; i <= n; i++){
                int l = binary_search(1, mm, li[i]);
                int r = binary_search(1, mm, ri[i]);
                update(l, r, i, 1, mm, 1);
                //printf("%d - %d : %d
    ", l, r, i);
            }
            ans = 0;
            query(1, mm, 1);
            printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    基于Spring aop写的一个简单的耗时监控
    Intellij Idea 15 旗舰版 破解
    设计模式之工厂模式
    IDE神器intellij idea的基本使用
    [js] js判断浏览器(转)
    java知识大全积累篇
    一些技术大牛的博客集锦(转)
    添加鼠标右击菜单
    java 方法调用绑定
    Android系列--DOM、SAX、Pull解析XML
  • 原文地址:https://www.cnblogs.com/quasar/p/5224502.html
Copyright © 2020-2023  润新知