POJ_2528

    首先说明一点,直接离散化海报的端点是不行的,因为这样会默认把海报范围内的所有端点都覆盖掉后就算把海报覆盖了,然而实际上是不可以这样判断的。比如1 10、1 4、6 10这三张海报,尽管最后1、4、6、10都被覆盖了,但是5这个单位线段是没有被覆盖的,所以应该输出3。

    为了避免上述的问题,我们在离散的话的时候可以选择将区间离散化,海报的端点算作一个区间,相邻两个端点之间也算所一个区间,那么上面的例子就被离散化成了1 1、2 3、4 4、5 5、6 6、7 9、10 10这样几个区间,还有更方便一点的做法,就是不去离散化区间,但是添加上海报端点左边的点,对于上面的例子离散化之后就是1、3、4、5、6、9、10,当然添加端点右边的点也是可以的。

    剩下的操作就是对区间染色了,最后在统计一下树上有多少不同的颜色即可。

View Code // 离散化区间
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXP 10010
#define MAXD 40010
struct Poster
{
int x, y;
}p[MAXP], st[MAXD];
int N, P, tx[MAXD], to[4 * MAXD], h[MAXP];
int cmp(const void *_p, const void *_q)
{
int *p = (int *)_p, *q = (int *)_q;
return *p - *q;
}
void build(int cur, int x, int y)
{
int mid = (x + y) / 2, ls = 2 * cur, rs = 2 * cur + 1;
to[cur] = -1;
if(x == y)
return ;
build(ls, x, mid);
build(rs, mid + 1, y);
}
void init()
{
int i, k = 0;
scanf("%d", &P);
for(i = 0; i < P; i ++)
{
scanf("%d%d", &p[i].x, &p[i].y);
tx[k ++] = p[i].x;
tx[k ++] = p[i].y;
}
qsort(tx, k, sizeof(tx[0]), cmp);
N = 0;
for(i = 0; i < k; i ++)
if(!i || tx[i] != tx[i - 1])
{
if(i && tx[i] - tx[i - 1] > 1)
{
st[N].x = tx[i - 1] + 1, st[N].y = tx[i] - 1;
++ N;
}
st[N].x = st[N].y = tx[i];
++ N;
}
build(1, 0, N - 1);
}
void pushdown(int cur)
{
if(to[cur] != -1)
{
int ls = 2 * cur, rs = 2 * cur + 1;
to[ls] = to[rs] = to[cur];
to[cur] = -1;
}
}
void color(int cur, int x, int y, int s, int t, int c)
{
int mid = (x + y) / 2, ls = 2 * cur, rs = 2 * cur + 1;
if(st[x].x >= s && st[y].y <= t)
{
to[cur] = c;
return ;
}
pushdown(cur);
if(st[mid].y >= s)
color(ls, x, mid, s, t, c);
if(st[mid + 1].x <= t)
color(rs, mid + 1, y, s, t, c);
}
void getans(int cur, int x, int y, int &cnt)
{
int mid = (x + y) / 2, ls = 2 * cur, rs = 2 * cur + 1;
if(to[cur] != -1)
{
if(!h[to[cur]])
{
++ cnt;
h[to[cur]] = 1;
}
return ;
}
getans(ls, x, mid, cnt);
getans(rs, mid + 1, y, cnt);
}
void solve()
{
int i, cnt = 0;
for(i = 0; i < P; i ++)
color(1, 0, N - 1, p[i].x, p[i].y, i);
memset(h, 0, sizeof(h[0]) * P);
getans(1, 0, N - 1, cnt);
printf("%d\n", cnt);
}
int main()
{
int t;
scanf("%d", &t);
while(t --)
{
init();
solve();
}
return 0;
}

 

View Code // 离散化点
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXP 10010
#define MAXD 40010
struct Poster
{
int x, y;
}p[MAXP];
int N, P, tx[MAXD], st[MAXD], to[4 * MAXD], h[MAXP];
int cmp(const void *_p, const void *_q)
{
int *p = (int *)_p, *q = (int *)_q;
return *p - *q;
}
void build(int cur, int x, int y)
{
int mid = (x + y) / 2, ls = 2 * cur, rs = 2 * cur + 1;
to[cur] = -1;
if(x == y)
return ;
build(ls, x, mid);
build(rs, mid + 1, y);
}
void init()
{
int i, k = 0;
scanf("%d", &P);
for(i = 0; i < P; i ++)
{
scanf("%d%d", &p[i].x, &p[i].y);
tx[k ++] = p[i].x;
tx[k ++] = p[i].y;
}
qsort(tx, k, sizeof(tx[0]), cmp);
N = 0;
for(i = 0; i < k; i ++)
{
if(i && tx[i] - tx[i - 1] > 1)
st[N ++] = tx[i] - 1;
if(!i || tx[i] != tx[i - 1])
st[N ++] = tx[i];
}
build(1, 0, N - 1);
}
void pushdown(int cur)
{
if(to[cur] != -1)
{
int ls = 2 * cur, rs = 2 * cur + 1;
to[ls] = to[rs] = to[cur];
to[cur] = -1;
}
}
void color(int cur, int x, int y, int s, int t, int c)
{
int mid = (x + y) / 2, ls = 2 * cur, rs = 2 * cur + 1;
if(st[x] >= s && st[y] <= t)
{
to[cur] = c;
return ;
}
pushdown(cur);
if(st[mid] >= s)
color(ls, x, mid, s, t, c);
if(st[mid + 1] <= t)
color(rs, mid + 1, y, s, t, c);
}
void getans(int cur, int x, int y, int &cnt)
{
int mid = (x + y) / 2, ls = 2 * cur, rs = 2 * cur + 1;
if(to[cur] != -1)
{
if(!h[to[cur]])
{
++ cnt;
h[to[cur]] = 1;
}
return ;
}
getans(ls, x, mid, cnt);
getans(rs, mid + 1, y, cnt);
}
void solve()
{
int i, s, t, cnt = 0;
for(i = 0; i < P; i ++)
color(1, 0, N - 1, p[i].x, p[i].y, i);
memset(h, 0, sizeof(h[0]) * P);
getans(1, 0, N - 1, cnt);
printf("%d\n", cnt);
}
int main()
{
int t;
scanf("%d", &t);
while(t --)
{
init();
solve();
}
return 0;
}


posted on 2012-03-31 13:38  Staginner  阅读(188)  评论(0编辑  收藏  举报