题意:
墙上有n张海报,每张海报在水平方向有覆盖的范围,问贴上n张海报后还能看见的有多少张。
需要注意的是,题目中的覆盖范围应该如下图所示:
|-1-|-2-|-3-|-4-|
而不是
| - | - | - | - |
1 -2-3- 4 -5
因为题目的数据范围较大所以要对坐标进行离散化。
如把2,100,5000,12321离散成0,1,2,3。
同时要注意区间1,2 3,4和1,2 4,5的区别。
对线段树的细节还没理解到位.. WA了几发..
代码:
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
#define MAXN 11111
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid int m = (l + r ) >> 1
int le[MAXN],ri[MAXN];
bool book[MAXN];
vector <int> vet;
vector <int> vet2;
int col[MAXN<<4];
int ans;
void build(int l,int r,int rt)
{
col[rt] = -1;
if(l == r)
return;
mid;
build(lson);
build(rson);
}
void PushDown(int rt)
{
if(col[rt] != -1)
{
col[rt<<1] = col[rt<<1|1] = col[rt];
col[rt] = -1;
}
}
void update(int L,int R,int c,int l,int r,int rt)
{
if(L <= l && r <= R)
{
col[rt] = c;
return;
}
PushDown(rt);
mid;
if(m>=L) update(L,R,c,lson);
if(m<R) update(L,R,c,rson);
}
void query(int l,int r,int rt)
{
if(col[rt]!=-1)
{
if(!book[col[rt]]) ans++;
book[col[rt]] = true;
return;
}
if(l == r)
return;
mid;
query(lson);
query(rson);
}
int main()
{
ios::sync_with_stdio(false);
int T,n,len;
cin>>T;
while(T--){
cin>>n;
ans = 0;
memset(book,0,sizeof(book));
vet.clear();
vet2.clear();
int nn =0;
for(int i = 0;i<n;i++)
{
cin>>le[i]>>ri[i];
vet.push_back(le[i]);
vet.push_back(ri[i]);
}
sort(vet.begin(),vet.end());
vet2.push_back(vet[0]);
for(int i = 1;i<vet.size();i++)
if(vet[i]!=vet[i-1])
vet2.push_back(vet[i]);
int tmp = vet2.size();
for(int i = 1;i<tmp;i++)
if(vet2[i]!=vet2[i-1]+1)
vet2.push_back(vet2[i-1]+1);
len = vet2.size();
sort(vet2.begin(),vet2.end());
memset(col,-1,sizeof(col));
for(int i = 0;i<n;i++)
{
int l = (lower_bound(vet2.begin(),vet2.end(),le[i]) - vet2.begin());
int r = (lower_bound(vet2.begin(),vet2.end(),ri[i]) - vet2.begin());
update(l,r,i,0,len,1);
}
query(0 , len , 1);
cout<<ans<<endl;
}
}