题目链接: http://acm.pku.edu.cn/JudgeOnline/bbs?problem_id=2528
这题又是线段树+离散化
慢慢的对离散化有点感觉了,但是这题我还是错了3次
题目大意是一层一层地叠板子,问最后能看到几块
输入是板子的开始和结束位置
由于输入的是闭区间线段开始我就构造闭区间线段的线段树,但是后来发现很多问题,
比如构造线段树的时候有区间1-4–>1-2+3-4.如果1映射到位置1,2映射到4,3映射到8,4映射到12,那么5,6,7三个点就丢失了
所以后来改成了半开半闭区间,结果还是出了点问题,最后开成完全开区间才AC
也就是线段树表示两个端点,,比如位置1两端的端点是0和1,那么测试数据就有
(0 4)
(1 6)
(7 10)
(2 4)
(6 10)
五个开区间
然后在旧时一般的离散化+线段树了
贴代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 10005
struct node
{
long l,r,h;
};
long buildTree(long l,long r,long pos);
void addHeight(long l,long r,long pos,long h);
void dealData(long &n,long pos);
node old[MAXN],newT[MAXN * 10];
bool isShowed[MAXN];
long tn,num,index[MAXN * 2];
int main()
{
int t,n;
scanf("%d",&t);
while(t --)
{
memset(old,0,sizeof(old));
memset(newT,0,sizeof(newT));
memset(index,0,sizeof(index));
memset(isShowed,false,sizeof(isShowed));
int i,j;
num = tn = 0;
scanf("%d",&n);
for(i = 0 ; i < n ; i ++)
scanf("%ld %ld",&old[i].l , &old[i].r) ,old[i].h = i + 1
, index[num ++] = old[i].l - 1 , index[num ++] = old[i].r;
sort(index , index + num);
j = 1;
for(i = 1 ; i < num ; i ++)
if(index[i] != index[j - 1])
index[j ++] = index[i];
index[j] = index[j - 1] + 1;
num = j;
buildTree(0,num - 1, 1);
for(i = 0 ; i < n ; i ++)
addHeight(old[i].l - 1 , old[i].r ,1, old[i].h);
dealData(tn , 1);
j = 0;
for(i = 0 ; i < MAXN ; i ++)
j += isShowed[i]?1:0;
printf("%d\n",j);
}
return 0;
}
long buildTree(long l,long r,long pos)
{
newT[pos].l = l;
newT[pos].r = r;
newT[pos].h = 0;
long mid = (l + r) >> 1;
tn = (pos > tn)? pos : tn;
if(r > l + 1)
return 1 + buildTree(l , mid, 2 * pos) + buildTree(mid , r, 2 * pos + 1);
else
return 1;
}
void addHeight(long l,long r,long pos,long h)
{
if(l == index[newT[pos].l] && r == index[newT[pos].r])
{
newT[pos].h = h;
return;
}
if(newT[pos].l >= newT[pos].r)
return;
long mid = (newT[pos].l + newT[pos].r) >> 1;
if(newT[pos].h)
{
newT[2 * pos].h = newT[pos].h;
newT[2 * pos + 1].h = newT[pos].h;
newT[pos].h = 0;
}
if(index[mid] >= r)
addHeight(l,r,2 * pos, h);
else if(index[mid] <= l)
addHeight(l,r,2 * pos + 1, h);
else
{
addHeight(l,index[mid],2 * pos, h);
addHeight(index[mid],r,2 * pos + 1, h);
}
}
void dealData(long &n,long pos)
{
if(newT[pos].h)
{
isShowed[newT[pos].h] = true;
return;
}
if(2 * pos <= tn)
dealData(n,2 * pos);
if(2 * pos + 1 <= tn)
dealData(n,2 * pos + 1);
}