失踪百景

惯性生存者

导航

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\n", 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\n", 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\n", l, r, i);
        }
        ans = 0;
        query(1, mm, 1);
        printf("%d\n", ans);
    }
    return 0;
}

 

posted on 2016-02-28 12:26  失踪百景  阅读(240)  评论(0编辑  收藏  举报