poj 2528 Mayor's posters(线段树+离散化,染色)

小记:这题真TMD烦啊,我一个建树出现了一点小问题,就是没有建立起叶子节点像(1,1) (2,2)等这样的点,导致了答案一直错,连样例都过不了,但是我又想不通哪里错了

QAQ


思路:首先hash离散化,有用线段树做矩形交面积等题的应该会有用到的时候,离散化就是将原本离的很开的点,变成连续的点,这样建树就不会MLE了。

例如原本是 2  10  100  1000,离散化一下就变成

1  2  3  4

就这样。

离散化的原因就是因为题目的数据,一个1千万,一个1万,必须离散化

然后线段树就是为每一个海报插入线段树,然后标记所染的色,之前有的也覆盖掉。

线段树节点加一个颜色标记,表示这一段是什么颜色,

在这里-1表示多色,0表示无色,大于0表示单色

循环的插入线段树里,对每一段依次染色,完成染色之后就是计算结果了

递归求解,如果某一段是单色那么就看这个颜色是否被标记了,没有被标记那么就标记,然后答案就+1,否则就继续往下递归,无色的就不要递归了。


代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>

using namespace std;

#define mst(a,b) memset(a,b,sizeof(a))
#define REP(a,b,c) for(int a = b; a < c; ++a)
#define eps 10e-8

const int MAX_ = 10010;
const int N = 10000010;
const int INF = 0x7fffffff;

struct node{
    int l, r;
    int col;
}tree[MAX_*8];

int ans;
int a[MAX_], b[MAX_];
int x[MAX_*2];
int hash[N];
bool vis[MAX_];

void build(int l, int r, int k)
{

    int mid = l + (r-l)/2;
    tree[k].l = l;
    tree[k].r = r;
    tree[k].col = 0;

    if(l == r){
        return ;
    }
    build(l, mid, k<<1);
    build(mid+1, r, (k<<1)|1);

}

void insert(int col, int l, int r, int k)
{
    if(l > tree[k].r || r < tree[k].l){return ;}

    if(l <= tree[k].l &&  r >= tree[k].r){
        tree[k].col = col;
        return ;
    }

    if(tree[k].col >= 0){
        tree[k<<1].col = tree[(k<<1)|1].col = tree[k].col;
        tree[k].col = -1;
    }

    insert(col, l, r, k<<1);
    insert(col, l, r, (k<<1)|1);
}

void query(int k)
{
    if(tree[k].col == 0)return ;

    if(tree[k].col > 0){
        if(!vis[tree[k].col]){
            vis[tree[k].col] = 1;
            ans++;
        }
        return ;
    }

    if(tree[k].col == -1){
        query(k<<1);
        query(2*k+1);
    }
    return;
}


int main(){
	int n, m, cnt, T;
	scanf("%d", &T);
	while(T-- && scanf("%d", &n)){
	    cnt = 0;
	    ans = 0;
	    mst(vis, 0);
        REP(i, 0, n){
            scanf("%d%d", &a[i], &b[i]);
            x[cnt++] = a[i];
            x[cnt++] = b[i];
        }
        sort(x, x+cnt);

        cnt = unique(x, x+cnt) - x;

        m = 0;
        REP(i, 0, cnt){
            hash[x[i]] = ++m;
        }

        build(1, m, 1);

        REP(i, 0, n){
            insert(i+1, hash[a[i]], hash[b[i]], 1);
        }

        query(1);

        printf("%d\n", ans);

	}
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章