您的位置:首页 > 其它

POJ 2528 Mayor's Poster(还是线段树,外加离散化)

2012-07-04 22:16 309 查看
题目意思是在一道墙上贴海报,后面贴的海报可能把前面的覆盖,之后给出一个区间,要输出这个区间内能够看见的海报数目。

乍一看非常像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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: