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;
}



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