题意:
往高度为1的广告牌上贴广告,广告之间能覆盖,问最后能看见几个
思路:
复习线段树就又写一遍,发现用STL离散和补点非常方便,就是跑得满了很多
错误及反思:
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int INF=2e6+10;
int segtree[INF<<2];
int l[INF],r[INF];
vector<int> v;
vector<int> t;
bool did[INF];
int w;
int getid(int x){return lower_bound(v.begin(),v.end(),x)-v.begin();}
void init(int l,int r,int rt){
if(l==r)
{
segtree[rt]=-1;
return ;
}
int m=(l+r)>>1;
init(lson);
init(rson);
segtree[rt]=-1;
}
void pushdown(int rt){
segtree[rt<<1]=segtree[rt];
segtree[rt<<1|1]=segtree[rt];
segtree[rt]=-1;
}
void update(int L,int R,int val,int l,int r,int rt)
{
if(L<=l&&R>=r){
segtree[rt]=val;
return ;
}
if(segtree[rt]!=-1) pushdown(rt);
int m=(l+r)>>1;
if(m>=L) update(L,R,val,lson);
if(m<R) update(L,R,val,rson);
return ;
}
void query(int l,int r,int rt)
{
if(segtree[rt]!=-1)
{
did[segtree[rt]]=true;
return ;
}
if(l==r) return ;
int m=(l+r)>>1;
query(lson);
query(rson);
}
int main(){
int T;
scanf("%d",&T);
while(T--)
{
memset(segtree,-1,sizeof(segtree));
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d%d",&l[i],&r[i]);
for(int i=0;i<n;i++)
{
v.push_back(l[i]);
v.push_back(r[i]);
}
sort(v.begin(),v.end());
for(int i=1;i<v.size();i++)
{
if(v[i]-v[i-1]!=1&&v[i]!=v[i-1])
t.push_back(v[i-1]+1);
}
for(int i=0;i<t.size();i++)
v.push_back(t[i]);
sort(v.begin(),v.end()),v.erase(unique(v.begin(),v.end()),v.end());
init(0,v.size()-1,1);
for(int i=0;i<n;i++){
int ta=getid(l[i]);
int tb=getid(r[i]);
update(ta,tb,i,0,v.size()-1,1);
}
memset(did,false,sizeof(did));
query(0,v.size()-1,1);
int ans=0;
for(int i=0;i<INF;i++)
if(did[i]) ans++;
printf("%d\n",ans);
v.clear();t.clear();
}
}