您的位置:首页 > 其它

poj 2528 Mayor’s posters 线段树

2015-11-03 21:16 302 查看
//	poj 2528 Mayor’s posters
//
//	题目大意:
//		给你n张海报,每张海报是一段区间,问最后由几张还好能露出来
//
//	解题思路:
//		线段树,别看那海报的区间范围很大,其实那些都没用.n才10000呢
//	将区间离散化之后,然后在进行线段树的操作,但是注意在相差大于1
//	的区间中间加上一个值,这样讲两个区间区分开,然后就是基本操作了
//	挺好想的

#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#define For(x,a,b,c) for (int x = a; x <= b; x += c)
#define Ffor(x,a,b,c) for (int x = a; x >= b; x -= c)
#define cls(x,a) memset(x,a,sizeof(x))
using namespace std;
typedef long long ll;

const double PI = acos(-1.0);
const double EPS = 1e-10;
const int MAX_N = 80000;
const int INF = 10009;
int N,M;

int L[MAX_N],R[MAX_N];
int a[MAX_N];
int cnt;

struct IntervalTree{

#define ls(x)	(x << 1)
#define rs(x)	(x << 1 | 1)
int col[MAX_N<<2];

bool isc[MAX_N];

void init(){
cls(col,-1);
cls(isc,0);
}

void push_down(int rt){
if (col[rt]!=-1){
col[ls(rt)] = col[rs(rt)] = col[rt];
col[rt] = -1;
}
}

void update(int rt,int L,int R,int ql,int qr,int v){
if (ql <= L && R <= qr){
col[rt] = v;
return ;
}

push_down(rt);

int M = (L + R) >> 1;

if (ql <= M)	update(ls(rt),L,M,ql,qr,v);
if (M < qr)		update(rs(rt),M+1,R,ql,qr,v);
push_down(rt);
}

void query(int rt,int L,int R){
if (col[rt] != -1){
if (!isc[col[rt]])
cnt++;
isc[col[rt]] = 1;
return ;
}
if(L == R) return ;
int M = (L + R) >> 1;
query(ls(rt),L,M);
query(rs(rt),M+1,R);
}

}it;

void input(){
scanf("%d",&N);
int tot = 1;
for (int i = 1;i <= N;i ++){
scanf("%d%d",&L[i],&R[i]);
a[tot++] = L[i];
a[tot++] = R[i];
}

sort(a+1,a+tot);
int m = 2;

for (int i = 2;i < tot ; i++){
if (a[i] != a[i-1])
a[m++] = a[i];
}
tot = m;

for (int i = tot - 1;i >= 2;i --){
if (a[i] - a[i-1] > 1)
a[m++] = a[i-1] + 1;
}

tot = m;

sort(a + 1, a + tot);

it.init();

for (int i = 1;i <= N;i ++){
int l = lower_bound(a + 1,a + tot, L[i]) - a;
int r = lower_bound(a + 1,a + tot, R[i]) - a;

it.update(1,1,tot-1,l,r,i);
}

cnt = 0;

it.query(1,1,tot-1);

printf("%d\n",cnt);

}

int main(){
int t;
//freopen("1.in","r",stdin);
scanf("%d",&t);
while(t--){
input();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息