POJ 2528 Mayor's Poster(還是線段樹,外加離散化)

題目意思是在一道牆上貼海報,後面貼的海報可能把前面的覆蓋,之後給出一個區間,要輸出這個區間內能夠看見的海報數目。

乍一看非常像POJ 2777塗顏料那道題目,仔細一想還是有很大的不同。首先海報數量十分巨大,不可能用上位運算,這也意味着每次query都要查詢到線段樹的葉。其次牆所表示的區間十分大,即時能夠被 __int64 表示,過大的區間也很容易造成MLE。所以要用上離散化,將整個區間縮小到相對極小的範圍內(其實不知道爲啥這叫離散化。。)。

最後的代碼AC了,但其實還是有問題,離散化的時候沒有處理好,導致區間之間的間隙變成了0。可是還是過了,可能是數據太弱。另外也用了lazy,不過可能即使不用也能過。

#include<cstdio>
#include<set>
#include<algorithm>
#include<iostream>
#define MID(x, y)  (x + y >> 1)
#define L(x) (x) << 1
#define R(x) (x) << 1 | 1

using namespace std;

typedef struct{
	int l, r;
	int post;
	int offset;
} NODE;


typedef struct {
	int val;
	int id;
	bool isLeft;
} MAP;
MAP input[40000];
NODE st[88000];
int Left[20000], Right[20000];
set<int> result;

void build(long long t, int l, int r){
	st[t].l = l;
	st[t].r = r;
	st[t].post = 0;
	st[t].offset = 0;
	if(l == r)
		return;
	else{
		build(L(t), l, MID(l, r));
		build(R(t), MID(l, r) + 1, r);
	}
}

void update(long long t, int l, int r, int p){
	if(st[t].l == l && st[t].r == r){
		st[t].post = p;
		st[t].offset = p;
		return;	
	}
	if(st[t].offset && st[t].l != st[t].r){
		st[L(t)].post = st[t].offset;
		st[R(t)].post = st[t].offset;
		st[L(t)].offset = st[t].offset;
		st[R(t)].offset = st[t].offset;
		st[t].offset = 0;
	}
	st[t].post = -1;
	int mid = MID(st[t].l, st[t].r);
	if(mid >= r){
		update(L(t), l, r, p);
	}else if(mid < l){
		update(R(t), l, r, p);
	}else{
		update(L(t), l, mid, p);
		update(R(t), mid + 1, r, p);
	}
}

void query(int t, int l, int r){
	if(st[t].l == l && st[t].r == r && st[t].post != -1){
		result.insert(st[t].post);
		return;
	}
	if(st[t].offset){
		st[L(t)].post = st[t].offset;
		st[R(t)].post = st[t].offset;
		st[L(t)].offset = st[t].offset;
		st[R(t)].offset = st[t].offset;
		st[t].offset = 0;
	}
	st[t].post = -1;
	int mid = MID(st[t].l, st[t].r);
	if(mid >= r){
		query(L(t), l, r);
	}else if(mid < l){
		query(R(t), l, r);
	}else{
		query(L(t), l, mid);
		query(R(t), mid + 1, r);
	}		
}	

bool cmp(MAP a, MAP b){
	return a.val < b.val;
}

int main(){
	int N;
	scanf("%d", &N);
	while(N--){
		int O;
		scanf("%d", &O);
		for(int i = 1; i <= O; i++){
			int x, y;
			scanf("%d %d", &input[i * 2 - 1].val, &input[i * 2].val);
			input[i * 2 - 1].id = i;
			input[i * 2 - 1].isLeft = true;
			input[i * 2].id = i;
			input[i * 2].isLeft = false;
		}
		sort(input + 1, input + 2 * O + 1, cmp);
	
		int value = input[1].val;
		int t = 1;
		for(int i = 1; i <= 2 * O; i++){
			if(value != input[i].val){
				value = input[i].val;
				t++;
			}
		//	cout << input[i].id << " " << input[i].val << " " << t << endl;
			if(input[i].isLeft){
				Left[input[i].id] = t;
			}else{
				Right[input[i].id] = t;
			}
		}
	//	for(int i = 1; i <= O; i++){
//			cout << Left[i] <<" " << Right[i] << endl;
//		}
		build(1, 1, 20000);
		for(int i = 1; i <= O; i++){
//			cout << Left[i] << Right[i]<<endl;;
			update(1, Left[i], Right[i], i);
		}
		result.clear();
		query(1, 1, 20000);
		result.insert(0);
		result.insert(-1);
		cout << result.size() - 2 << endl;
	}
}


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