POJ 2528 Mayor's posters

/*
按照大牛博客顺序做的题目
以前离散化好好理解了下
注意离散化后 struct SegTree{
int l, r;
int color;
int getMid(){
return (l + r) >> 1;
}
}tree[MAXN
<< 2];
中l,r不是原区间的坐标了,而是排序去重后数组中对应的下标
做这题问题不大 基本上1A 第一次数组开小了 囧.
*/
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#define L(x) ((x) << 1)
#define R(x) ((x) << 1 | 1)
#define MAXN 100100

struct SegTree{
int l, r;
int color;
int getMid(){
return (l + r) >> 1;
}
}tree[MAXN
<< 2];

struct Query{ //询问区间的数据结构
int left, right;
}q[
10010];
bool hash[10010]; //统计颜色用的
int bin[20020];

int cmp(const void *a, const void *b){
return *(int *)a - *(int *)b;
}
int bs(int left, int right, int tar){ //二分查找区间坐标在bin中的位置
while(left <= right){
int mid = (left + right) >> 1;
if(bin[mid] == tar)
return mid;
if(bin[mid] > tar)
right
= mid - 1;
else
left
= mid + 1;
}
}
void bulid(int left, int right, int t){
tree[t].l
= left;
tree[t].r
= right;
tree[t].color
= 0;
if(left == right)
return;
int mid = tree[t].getMid();
bulid(left, mid, L(t));
bulid(mid
+ 1, right, R(t));
}
void insert(int left, int right, int color, int t){
if(left <= tree[t].l && right >= tree[t].r){
tree[t].color
= color;
return;
}
if(tree[t].color != -1){
tree[L(t)].color
= tree[R(t)].color = tree[t].color;
tree[t].color
= -1;
}
int mid = tree[t].getMid();
if( right <= mid ){
insert(left, right, color, L(t));
}
else if( left > mid ){
insert(left, right, color, R(t));
}
else {
insert(left, mid, color, L(t));
insert(mid
+ 1, right, color, R(t));
}
if(tree[L(t)].color == tree[R(t)].color && tree[L(t)].color != -1){
tree[t].color
= tree[L(t)].color;
}
}
int query(int t){
if( tree[t].l == tree[t].r ){
if( tree[t].color != -1 ){
if( !hash[tree[t].color] ){
hash[tree[t].color]
= true;
return 1;
}
else
return 0;
}
}
if( tree[t].color != -1 ){
if( !hash[tree[t].color] ){
hash[tree[t].color]
= true;
return 1;
}
else{
return 0;
}
}
return query(L(t)) + query(R(t));
}
int main(){
int t, n;
scanf(
"%d",&t);
while( t-- ){
int num = 1;
scanf(
"%d",&n);
for(int i = 1; i <= n; ++i){
scanf(
"%d%d",&q[i].left, &q[i].right);
bin[num
++] = q[i].left;
bin[num
++] = q[i].right;
}
//升序排序
qsort(bin + 1, num - 1, sizeof(bin[0]), cmp);//bin从1开始 个数num-1个
//去重
int cnt = 1;
for(int i = 2; i < num; ++i){
if(bin[i] != bin[i - 1])
bin[
++cnt] = bin[i];
}
bulid(
1, cnt, 1);
for(int i = 1; i <= n; ++i){
int l = bs(1, cnt, q[i].left);
int r = bs(1, cnt, q[i].right);
insert(l, r, i,
1);
}
memset(hash,
false, sizeof(hash));
hash[
0] = true;
printf(
"%d\n",query(1));
}
return 0;
}
posted @ 2011-04-12 14:33  L..  阅读(203)  评论(0编辑  收藏  举报