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

你可能感兴趣的:(post)